title: Pygame object has no attribute 'rect' (pygame)
body: <p>I'm currently making Memory, a game for school which involves matching 8 pairs of images that are hidden underneath covers. I was successful in setting up the 4x4 grid, with a timer for score and randomizing the location of the images, but removing the cover on the tiles is giving me some issues. I end up getting the error: builtins.AttributeError: type object 'Tile' has no attribute 'rect'</p>
  
  <p>The traceback is:</p>
  
  <pre><code>Traceback (most recent call last):
    File "/home/user/Documents/Lab 4/memory2cover.py", line 179, in &lt;module&gt;
      main()
    File "/home/user/Documents/Lab 4/memory2cover.py", line 21, in &lt;module&gt;
      game.play()
    File "/home/user/Documents/Lab 4/memory2cover.py", line 92, in &lt;module&gt;
      self.handle_events()
    File "/home/user/Documents/Lab 4/memory2cover.py", line 117, in &lt;module&gt;
      Tile.handle_click(Tile, event)
    File "/home/user/Documents/Lab 4/memory2cover.py", line 175, in &lt;module&gt;
      if self.rect.collidepoint(pos):
  builtins.AttributeError: type object 'Tile' has no attribute 'rect'
  </code></pre>
  
  <p>My Tile class is:</p>
  
  <pre><code>class Tile:
     # An object in this class represents a Tile 
     # Shared or Class Attributes
     surface = None
     fg_color = pygame.Color('black')
     border_width = 10
     cover = pygame.image.load('image0.bmp')
  
     @classmethod
     def set_surface(cls,surface_from_Game):
        cls.surface = pygame.display.get_surface()
  
     def __init__(self, x,y,width,height, image):
        # Initialize a Tile.
        # - self is the Tile to initialize
        # - x,y top left coordinates of the rectangle
        # - - width, height are the dimensions of the rectangle
        # Instance Attributes or Object Attributes
        self.rect = pygame.Rect(x,y,width,height)
        self.image = image
        self.covered = True
  
     def draw(self):
        # Draw the dot on the surface
        # - self is the Tile
        # then blit the tile content onto the surface
        pygame.draw.rect(Tile.surface, Tile.fg_color, self.rect,Tile.border_width)
        if self.covered:
           Tile.surface.blit(Tile.cover, self.rect)
        else:
           Tile.surface.blit(self.image, self.rect)
  
     def handle_click(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
           pos = pygame.mouse.get_pos()
           if self.rect.collidepoint(pos):
              self.covered = False
  </code></pre>
  
  <p>and I am not too sure why it is saying it has no attribute 'rect'.</p>
  
  <p>Here is my full code</p>
  
  <pre><code># Memory 1
  
  import pygame
  import random
  
  # User-defined functions
  # board[row_index][col_index]
  
  def main():
     # initialize all pygame modules (some need initialization)
     pygame.init()
     # create a pygame display window
     pygame.display.set_mode((500, 400))
     # set the title of the display window
     pygame.display.set_caption('Memory')   
     # get the display surface
     w_surface = pygame.display.get_surface() 
     # create a game object
     game = Game(w_surface)
     # start the main game loop by calling the play method on the game object
     game.play() 
     # quit pygame and clean up the pygame window
     pygame.display.quit()
     pygame.quit() 
  
  
  # User-defined classes
  
  class Game:
     # An object in this class represents a complete game.
  
     def __init__(self, surface):
        # Initialize a Game.
        # - self is the Game to initialize
        # - surface is the display window surface object
  
        # === objects that are part of every game that we will discuss
        self.surface = surface
        self.bg_color = pygame.Color('black')
  
        self.FPS = 70
        self.game_Clock = pygame.time.Clock()
        self.close_clicked = False
        self.continue_game = True
  
        # === game specific objects
        Tile.set_surface(self.surface) # this is how you call a class method
        self.board_size = 4
        self.board = []
        self.score = 0
        self.load_images()
        self.create_board()
        self.image_index = 0
  
  
     def load_images(self):
        # loads a specified amount of images into a list
        # that list of images is then shuffled so an images index is randomized
        self.image_list = []
        for self.image_index in range(1,9):
           self.image_list.append(pygame.image.load('image' + str(self.image_index) + '.bmp'))
        self.full_list = self.image_list + self.image_list
        random.shuffle(self.full_list)
  
     def create_board(self):
        # multiple rows and columns are appended to the board with the tiles added
        # utlizes the different images for each tile
        index = 0
        img = self.full_list[0]
        width = img.get_width()
        height = img.get_height()
        for row_index in range(0,self.board_size):
           self.row = []
           for col_index in range(0,self.board_size):
              #item = (row_index,col_index)
              # game = Game(), dot1 = Dot(), student = Student()
              image = self.full_list[index]
              x = width * col_index
              y = height * row_index      
              a_tile = Tile(x,y,width,height, image)
              self.row.append(a_tile)
              index = index + 1
           self.board.append(self.row)
  
  
     def play(self):
        # Play the game until the player presses the close box.
        # - self is the Game that should be continued or not.
  
        while not self.close_clicked:  # until player clicks close box
           # play frame
           self.handle_events()
           self.draw()            
           if self.continue_game:
              self.update()
           self.game_Clock.tick(self.FPS) # run at most with FPS Frames Per Second 
  
     def draw_score(self):
        fg = pygame.Color('white')
        bg = pygame.Color('black')
        font = pygame.font.SysFont('',70)
        text_box = font.render(str(self.score),True,fg,bg)
        #x = self.surface.get_width() - text_box.get_width()
        #y = self.surface.get_height() - text_box.get_height()
        location = (self.surface.get_width() -70,0)
        self.surface.blit(text_box,location)   
  
     def handle_events(self):
        # Handle each user event by changing the game state appropriately.
        # - self is the Game whose events will be handled
  
        events = pygame.event.get()
        for event in events:
           if event.type == pygame.QUIT:
              self.close_clicked = True
           for item in self.row:
              Tile.handle_click(Tile, event)
  
     def draw(self):
        # Draw all game objects.
        # - self is the Game to draw
        coordinates = self.create_board()
  
        # clear the display surface first
        self.surface.fill(self.bg_color) 
        # drawing of the board
        for row in self.board:
           for tile in row:
              tile.draw()
        self.draw_score()
        pygame.display.update() # make the updated surface appear on the display
  
     def update(self):
        # Update the game objects for the next frame.
        # - self is the Game to update
        self.score = pygame.time.get_ticks()//1000
  
  
  
  class Tile:
     # An object in this class represents a Tile 
     # Shared or Class Attributes
     surface = None
     fg_color = pygame.Color('black')
     border_width = 10
     cover = pygame.image.load('image0.bmp')
  
     @classmethod
     def set_surface(cls,surface_from_Game):
        cls.surface = pygame.display.get_surface()
  
     def __init__(self, x,y,width,height, image):
        # Initialize a Tile.
        # - self is the Tile to initialize
        # - x,y top left coordinates of the rectangle
        # - - width, height are the dimensions of the rectangle
        # Instance Attributes or Object Attributes
        self.rect = pygame.Rect(x,y,width,height)
        self.image = image
        self.covered = True
  
     def draw(self):
        # Draw the dot on the surface
        # - self is the Tile
        # then blit the tile content onto the surface
        pygame.draw.rect(Tile.surface, Tile.fg_color, self.rect,Tile.border_width)
        if self.covered:
           Tile.surface.blit(Tile.cover, self.rect)
        else:
           Tile.surface.blit(self.image, self.rect)
  
     def handle_click(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
           pos = pygame.mouse.get_pos()
           if self.rect.collidepoint(pos):
              self.covered = False
  
  
  main()
  </code></pre>