Копирование изображений на плитку, которая является частью сетки в pygame

avatar
Mathissohardlmao
1 декабря 2019 в 02:14
517
1
1
# User-defined functions
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.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

      self.surface = surface
      self.bg_color = pygame.Color('black')
      self.FPS = 60
      self.game_Clock = pygame.time.Clock()
      self.close_clicked = False
      self.continue_game = True

      Tile.set_surface(self.surface)              
      grid_size = 4
      self.create_grid(grid_size)
    def create_grid(self, grid_size):
      # Creates a grid of tiles that is grid_size x grid_size in size.

      self.grid = [ ]
      # this for loop creates each row in our grid     
      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):
      # Create one row in a grid. Each row contains size Tiles. a
#row_num is
      # required for calculating the tile's x,y coordinates on screen
      #  -  row_num: the nth row of the grid being created
      #  -   size  : the number of tiles in the row 
      # returns the newly created row'
      image_1=pygame.image.load('image1.bmp')
      image_2=pygame.image.load('image2.bmp')
      image_3=pygame.image.load('image3.bmp')
      image_4=pygame.image.load('image4.bmp')
      image_5=pygame.image.load('image5.bmp')
      image_6=pygame.image.load('image6.bmp')
      image_7=pygame.image.load('image7.bmp')
      image_8=pygame.image.load('image8.bmp')
      pygame_image_surfaces=[]
      pygame_image_surfaces.append(image_1)
      pygame_image_surfaces.append(image_2)
      pygame_image_surfaces.append(image_3)
      pygame_image_surfaces.append(image_4)
      pygame_image_surfaces.append(image_5)
      pygame_image_surfaces.append(image_6)
      pygame_image_surfaces.append(image_7)
      pygame_image_surfaces.append(image_8)
      pygame_image_surfaces=pygame_image_surfaces+pygame_image_surfaces


      random.shuffle(pygame_image_surfaces)
      image_surfaces=pygame_image_surfaces      





      tile_height = self.surface.get_height() // size
      tile_width = 3/4*self.surface.get_width() // size
      one_row = [ ]
      for col_num in range(size):
          y = row_num * tile_height
          x = col_num * tile_width
          pos = (x,y)
          one_tile = Tile(pos, tile_width, tile_height)
          i=0
          content = image_surfaces[i]
          i+=1
          one_tile.set_content(content)
          one_row.append(one_tile)
      return one_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.decide_continue()
          self.game_Clock.tick(self.FPS) # run at most with FPS Frames
#Per Second 
    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
          if event.type == pygame.MOUSEBUTTONDOWN:
            self.handle_mouse_click(event)
    def handle_mouse_click(self, event):
      # responds to one mouse click on screen; that means changing the
      # content of a tile if it is empty.
      print("Screen was clicked at " + str(event.pos))
    def draw(self):
      # Draw all game objects.
      # - self is the Game to draw
      self.surface.fill(self.bg_color) # clear the display surface
#first
      for row in self.grid:
          for tile in row:
            tile.draw()
      pygame.display.update() # make the updated surface appear on the
    def update(self):
      # Update the game objects for the next frame.
      # - self is the Game to update
      pass
    def decide_continue(self):
      # Check and remember if the game should continue
      # - self is the Game to check    
      return True
class Tile:
    # A tile represents one location on a grid. Tiles hold content

    # class attributes that are common to all tiles
    surface = None
    fg_color = pygame.Color("white")
    bg_color = pygame.Color("black")
    border_width = 3
    @classmethod
    def set_surface(cls, surface):
      # sets the class attribute, surface
      cls.surface = surface   
    def __init__(self, screen_position, width, height):
      # initialize one instance of our Tile class. Tiles represent
      # one 'position' in our  board.
      #  - self: the tile being initialized
      #  - screen_position: the [x, y] coordinates to draw the tile at
      #  - width: the width of the tile
      #  - height: the height of the tile
      self.screen_position = screen_position
      self.content = ''
      # create a rectangle defining our boundaries
      x, y = screen_position
      self.rect = pygame.Rect(x, y, width, height)
    def draw_content(self):
      image_1=pygame.image.load('image1.bmp')
      image_2=pygame.image.load('image2.bmp')
      image_3=pygame.image.load('image3.bmp')
      image_4=pygame.image.load('image4.bmp')
      image_5=pygame.image.load('image5.bmp')
      image_6=pygame.image.load('image6.bmp')
      image_7=pygame.image.load('image7.bmp')
      image_8=pygame.image.load('image8.bmp')
      pygame_image_surfaces=[]
      pygame_image_surfaces.append(image_1)
      pygame_image_surfaces.append(image_2)
      pygame_image_surfaces.append(image_3)
      pygame_image_surfaces.append(image_4)
      pygame_image_surfaces.append(image_5)
      pygame_image_surfaces.append(image_6)
      pygame_image_surfaces.append(image_7)
      pygame_image_surfaces.append(image_8)
      pygame_image_surfaces=pygame_image_surfaces+pygame_image_surfaces


      random.shuffle(pygame_image_surfaces)
      image_surfaces=pygame_image_surfaces
      for i in range(len(image_surfaces)):
          Tile.surface.blit(i)





      #Tile.surface.blit(text_img, text_pos)
    def draw(self):
      # draw the contents of a tile to its surface. 
      #  - self: the tile being drawn
      self.draw_content()
      pygame.draw.rect(Tile.surface, Tile.fg_color, self.rect,
Tile.border_width) 
    def set_content(self, new_content):

      #   - self: the tile whose content is being updated

      self.content = new_content
main()

Пытаюсь создать игру с памятью в pygame, но у меня проблемы с попыткой blit изображения на каждой отдельной плитке, и мне нужна помощь в устранении неполадок. То, что я пытаюсь сделать, это из списка файлов изображений, которые теперь являются объектами поверхности, я хотел бы blit по одному на каждую плитку. Но почему-то моя логика неверна. Я не уверен, должен ли этот материал входить в мой игровой класс или мой класс плитки, поскольку он описывает плитку, а не игру.

Tldr: не знаю, как blit изображения на каждой плитке из списка

Источник

Ответы (1)

avatar
Rabbid76
1 декабря 2019 в 10:09
1

Прежде всего, код, который определяет и загружает изображения, можно значительно упростить:

il = ['image' + str(i) + '.bmp' for i in range(1,9)]
pygame_image_surfaces = [pygame.image.load(os.path.join(path, name)) for name in imagenames]

Изображение, связанное с Tile, сохраняется в атрибуте экземпляра self.content объекта Tile. Используйте этот атрибут для рисования плитки:

class Tile:

    # [...]

    def draw_content(self):
        image_rect = self.content.get_rect(center = self.rect.center)
        Tile.surface.blit(self.content, image_rect)

    def draw(self):
        # draw the contents of a tile to its surface. 
        #  - self: the tile being drawn
        self.draw_content()
        pygame.draw.rect(Tile.surface, Tile.fg_color, self.rect, Tile.border_width) 

    def set_content(self, new_content):
        #   - self: the tile whose content is being updated
        self.content = new_content

Создайте 1 случайный список изображений. И используйте этот список, чтобы установить изображения для всей сетки плиток:

class Game:

    # [...]

    def create_grid(self, grid_size):
        # Creates a grid of tiles that is grid_size x grid_size in size.

        imgnames = ['image' + str(i) + '.bmp' for i in range(1,9)]
        image_surfaces = [pygame.image.load(os.path.join(path, name)) for name in imgnames]
        image_surfaces = image_surfaces + image_surfaces
        random.shuffle(image_surfaces)

        self.grid = []
        # this for loop creates each row in our grid  
        for row_num in range(grid_size):
            new_row = self.create_row(row_num, grid_size, image_surfaces)
            self.grid.append(new_row)

    def create_row(self, row_num, size, images):
        # Create one row in a grid. Each row contains size Tiles.
        # required for calculating the tile's x,y coordinates on screen
        #  -  row_num: the nth row of the grid being created
        #  -   size  : the number of tiles in the row 
        # returns the newly created row'

        tile_height = self.surface.get_height() // size
        tile_width = 3/4*self.surface.get_width() // size
        new_row = []
        for col_num in range(size):
              pos = (row_num * tile_height + 10, col_num * tile_width + 10)
              content = images[row_num*size + col_num]
              one_tile = Tile(pos, tile_width, tile_height)
              one_tile.set_content(content)
              new_row.append(one_tile)
        return new_row