2

I am coding a game called "Memory", which contains 8 pairs of images (16 images) in random order. When the game started, 16 of them have to show the same background images. After players click any tile, the tile flip from background images to foreground images. For now, I can't flip the tiles with collidepoint method. Please help me. Thank you very very much!

import pygame
import random
import time

screen = pygame.display.set_mode((525, 435))

def main():
   pygame.init()
   pygame.display.set_mode((535, 435))
   pygame.display.set_caption('Memory')
   w_surface = pygame.display.get_surface() 
   game = Game(w_surface)
   game.play()
   pygame.quit()

class Game:

   def __init__(self, surface):
      self.surface = surface
      self.bg_color = pygame.Color('black')
      self.FPS = 10
      self.game_Clock = pygame.time.Clock()
      self.close_clicked = False
      self.continue_game = True
      Tile.set_surface(self.surface)
      self.grid_size = 4
      self.grid = []
      self.score = 0
      imgnames = ['./images/' + str(i) + '.jpg' for i in range(1,9)]
      self.images = [pygame.image.load(name) for name in imgnames]
      self.shuffle = self.images + self.images
      random.shuffle(self.shuffle)
      self.create_grid(self.grid_size)

   def create_grid(self, grid_size):
      for row_num in range(grid_size):
         new_row = self.create_row(row_num, grid_size)
         self.grid.append(new_row)     

   def create_row(self, row_num, size):
      tile_height = self.surface.get_height() // size
      tile_width = self.surface.get_width() // (size+1)
      one_row = [ ]
      for col_num in range(size):
         y = row_num * tile_height + 5
         x = col_num * tile_width + 5
         i = col_num*size + row_num
         one_tile = Tile(x, y, tile_width, tile_height, self.shuffle[i], self.surface)
         one_row.append(one_tile)
      return one_row

   def play(self):
      while not self.close_clicked:
         self.handle_events()
         self.draw()
         if self.continue_game:
            self.update()
            self.decide_continue()
         self.game_Clock.tick(self.FPS)

   def handle_events(self):
      events = pygame.event.get()
      for event in events:
         if event.type == pygame.QUIT:
            self.close_clicked = True
         elif event.type == pygame.MOUSEBUTTONUP:
            position = pygame.mouse.get_pos()
            if pygame.MOUSEBUTTONUP.collidepoint(one_tile):
               self.flip = True


   def draw(self):
      self.surface.fill(self.bg_color)
      self.draw_score()
      for row in self.grid:
         for tile in row:
            tile.draw()
      pygame.display.update()

   def update(self):
      self.score = pygame.time.get_ticks() // 1000

   def decide_continue(self):
      pass

   def draw_score(self):
      score_string = str(self.score)    
      score_font = pygame.font.SysFont('', 48)
      score_fg_color = pygame.Color('white')
      score_image = score_font.render(score_string, True, score_fg_color)
      self.surface.blit(score_image, (500,10))

class Tile:
   def __init__(self, pos_x, pos_y, tile_numx, tile_numy, image, surface):
      self.pos_x = pos_x
      self.pos_y = pos_y
      self.numx = tile_numx
      self.numy = tile_numy
      self.image = image
      self.surface = surface
      self.flip = False

   @classmethod
   def set_surface(cls, surface):
      cls.surface = surface   

   def draw(self):
      x = 0
      y = 0
      i = 0
      if self.flip == False:
         screen.blit(pygame.image.load('./images/bg.jpg'),(self.pos_x,self.pos_y))
      elif self.flip == True:
         screen.blit(self.image,(self.pos_x,self.pos_y))



main()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Hu Jack
  • 65
  • 6

1 Answers1

2

Add a .rect attribute of type pygame.Rect to the class Tile. The rectangle has to have the position of the tile and the size of the image. It can be created by get_rect() from the image Surface:

class Tile:
   def __init__(self, pos_x, pos_y, tile_numx, tile_numy, image, surface):
      self.pos_x = pos_x
      self.pos_y = pos_y
      self.numx = tile_numx
      self.numy = tile_numy 
      self.image = image
      self.rect = self.image.get_rect(topleft = (self.pos_x,self.pos_y))
      self.surface = surface
      self.flip = False

   # [...]

Iterate through all tiles in the grid, when the the mouse button is pressed. Use collidepoint() to verify if the mouse is on the rectangle (tile.rect) which contains the area covered by a tile:

class Game:

   # [...] 

   def handle_events(self):
      events = pygame.event.get()
      for event in events:
         if event.type == pygame.QUIT:
            self.close_clicked = True
         elif event.type == pygame.MOUSEBUTTONUP:

            # get mouse position
            position = event.pos
            # position = pygame.mouse.get_pos() # <--- this would do the same

            # for all tiles
            for row in self.grid:
               for tile in row:

                  # test if mouse is on the tile and flip it
                  if tile.rect.collidepoint(position):
                     tile.flip = True
Rabbid76
  • 202,892
  • 27
  • 131
  • 174