统计图像数量并比较相似度 [英] Count images number and compared the similarity

查看:44
本文介绍了统计图像数量并比较相似度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个名为Memory"的游戏,其中包含随机顺序的 8 对图像(16 个图像).游戏开始时,其中 16 个必须显示相同的背景图像.玩家单击任何图块后,图块将从背景图像翻转为前景图像.如果两个前景图像相同,则它们保持不变.如果两个前景图像不同,它们会在几秒钟内消失.目前,我不知道如何检查它们的相似性.我尝试使用 self.count 来计算翻转图像的数量,但无法正常工作.请帮我.非常非常感谢!

导入pygame随机导入导入时间屏幕 = pygame.display.set_mode((525, 435))定义主():pygame.init()pygame.display.set_mode((535, 435))pygame.display.set_caption('内存')w_surface = pygame.display.get_surface()游戏 = 游戏(w_surface)游戏.play()pygame.quit()课堂游戏:def __init__(self,surface):self.surface = 表面self.bg_color = pygame.Color('黑色')self.FPS = 10self.game_Clock = pygame.time.Clock()self.close_clicked = Falseself.continue_game = TrueTile.set_surface(self.surface)self.grid_size = 4self.grid = []self.score = 0imgnames = ['./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.imagesrandom.shuffle(self.shuffle)self.create_grid(self.grid_size)def create_grid(self, grid_size):对于范围内的 row_num(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()//大小tile_width = self.surface.get_width()//(大小+1)one_row = [ ]对于范围(大小)中的 col_num:y = row_num * tile_height + 5x = col_num * tile_width + 5i = col_num*size + row_numone_tile = Tile(x, y, tile_width, tile_height, self.shuffle[i], self.surface)one_row.append(one_tile)返回 one_row定义播放(自我):而不是 self.close_clicked:self.handle_events()self.draw()如果 self.continue_game:自我更新()self.decide_continue()self.game_Clock.tick(self.FPS)def handle_events(self):事件 = pygame.event.get()对于事件中的事件:如果 event.type == pygame.QUIT:self.close_clicked = Trueelif event.type == pygame.MOUSEBUTTONUP:位置 = event.pos对于 self.grid 中的行:对于行中的瓷砖:如果 tile.rect.collidepoint(position):tile.flip = 真定义绘制(自我):self.surface.fill(self.bg_color)self.draw_score()对于 self.grid 中的行:对于行中的瓷砖:tile.draw()pygame.display.update()定义更新(自我):self.score = pygame.time.get_ticks()//1000定义决定_继续(自我):经过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, (430,10))类瓷砖:def __init__(self, pos_x, pos_y, tile_numx, tile_numy, image, surface):self.pos_x = pos_xself.pos_y = pos_yself.numx = tile_numxself.numy = tile_numyself.image = 图像self.surface = 表面self.flip = 假self.count = 0self.rect = self.image.get_rect(topleft = (self.pos_x,self.pos_y))@类方法def set_surface(cls, 表面):cls.surface = 表面定义绘制(自我):x = 0y = 0我 = 0如果 self.flip == False:screen.blit(pygame.image.load('./images/bg.jpg'),(self.pos_x,self.pos_y))elif self.flip == True:而 self.count <2:screen.blit(self.image,(self.pos_x,self.pos_y))self.count + 1主要的()

解决方案

Tile 类中移除属性 self.count.不需要:

class Tile:# [...]定义绘制(自我):x, y, i = 0, 0, 0如果 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))

<小时>

2 个图块是相等的,如果它们具有相同的图像.在您的代码中,2 个相等的图块共享相同的图像对象.比较图块的 .image 属性.例如如果有 tileAtileB,那么如果 tileA.image == tileB.image.

向类Game添加翻转的瓷砖列表:

class 游戏:def __init__(self,surface):# [...]self.flipped = []

如果按下鼠标按钮,则找到被点击"的图块并将其添加到翻转的图块中:

elif event.type == pygame.MOUSEBUTTONUP:对于 self.grid 中的行:对于行中的瓷砖:如果 tile.rect.collidepoint(event.pos) 而不是 tile.flip:tile.flip = 真self.flipped.append(tile)

如果self.flipped中的tile数量是偶数(len(self.flipped) % 2 == 0),则比较最后2个tile列表(self.flipped[-1], self.flipped[-2]).保持相同的瓷砖.如果瓦片不相等 (tileA.image != tileB.image),则将它们从 self.flipped 中移除并翻转回来:

if len(self.flipped) >0 和 len(self.flipped) % 2 == 0:tileA = self.flipped[-1]tileB = self.flipped[-2]如果 tileA.image != tileB.image:tileA.flip = FalsetileB.flip = Falseself.flipped = self.flipped[:-2]

这一切都可以应用于handle_events:

class 游戏:def __init__(self,surface):# [...]self.flipped = []# [...]def handle_events(self):事件 = pygame.event.get()对于事件中的事件:如果 event.type == pygame.QUIT:self.close_clicked = Trueelif event.type == pygame.MOUSEBUTTONUP:如果 len(self.flipped) >0 和 len(self.flipped) % 2 == 0:tileA = self.flipped[-1]tileB = self.flipped[-2]如果 tileA.image != tileB.image:tileA.flip = FalsetileB.flip = Falseself.flipped = self.flipped[:-2]对于 self.grid 中的行:对于行中的瓷砖:如果 tile.rect.collidepoint(event.pos) 而不是 tile.flip:tile.flip = 真self.flipped.append(tile)

请注意,图块在一段时间后不会翻转回来,而是在单击新图块时翻转回来.

<小时>

如果您希望图块在一段时间(例如 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. If two foreground images are the same, they stay. If two foreground images are different, they vanish in a few seconds. For now, I have no idea how to check their similarities. I try to use self.count to count the flipped images number, but cannot work. 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 = event.pos
               for row in self.grid:
                  for tile in row:
                     if tile.rect.collidepoint(position):
                        tile.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, (430,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
      self.count = 0
      self.rect = self.image.get_rect(topleft = (self.pos_x,self.pos_y))

   @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:
         while self.count < 2:
            screen.blit(self.image,(self.pos_x,self.pos_y))
            self.count + 1



main()

解决方案

Remove the attribute self.count from the class Tile. It is not needed:

class Tile:
  # [...]

  def draw(self):
      x, y, i = 0, 0, 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))


2 tiles are equal, if they have the same image. In your code 2 equal tiles share the same image object. Compare the .image attribute of the tiles. e.g. if there is a tileA and a tileB, then they are equal if tileA.image == tileB.image.

Add a list of the flipped tiles to the class Game:

class Game:

   def __init__(self, surface):
      # [...]

      self.flipped = []

If the mouse button is pressed, then find the tile which was "clicked" and add it to to flipped tiles:

elif event.type == pygame.MOUSEBUTTONUP:

    for row in self.grid:
        for tile in row:
            if tile.rect.collidepoint(event.pos) and not tile.flip:
                tile.flip = True
                self.flipped.append(tile)

If the number of tile in self.flipped is even (len(self.flipped) % 2 == 0), then compare the last 2 tiles in the list (self.flipped[-1], self.flipped[-2]). Keep equal tiles. If the tiles are not equal (tileA.image != tileB.image), then remove them from self.flipped and flip them back:

if len(self.flipped) > 0 and len(self.flipped) % 2 == 0:
    tileA = self.flipped[-1]
    tileB = self.flipped[-2] 
    if tileA.image != tileB.image:
        tileA.flip = False
        tileB.flip = False
        self.flipped = self.flipped[:-2]

That all can be applied to handle_events:

class Game:

   def __init__(self, surface):
      # [...]

      self.flipped = []


  # [...]

  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:

               if len(self.flipped) > 0 and len(self.flipped) % 2 == 0:
                  tileA = self.flipped[-1]
                  tileB = self.flipped[-2] 
                  if tileA.image != tileB.image:
                     tileA.flip = False
                     tileB.flip = False
                     self.flipped = self.flipped[:-2]

               for row in self.grid:
                  for tile in row:
                     if tile.rect.collidepoint(event.pos) and not tile.flip:
                        tile.flip = True
                        self.flipped.append(tile)

Note, the tiles do not flip back after a time span, but the flip back when on a new tile is clicked.


If you want that the tiles automatically flip back after a time span (e.g. 2 seconds), then I recommend to use a timer event.
A timer can be started by pygame.time.set_timer(). It can be stopped by passing time 0 to pygame.time.set_timer().

class Game:
   def __init__(self, surface):
      # [...]
      self.flipped = []

   def handle_events(self):
         timer_id = pygame.USEREVENT + 1

         events = pygame.event.get()
         for event in events:
            if event.type == pygame.QUIT:
               self.close_clicked = True
            elif event.type == timer_id:
               pygame.time.set_timer(timer_id, 0)
               if len(self.flipped) > 0 and len(self.flipped) % 2 == 0:
                  tileA, tileB = self.flipped[-1], self.flipped[-2] 
                  if tileA.image != tileB.image:
                     tileA.flip, tileB.flip = False, False
                     self.flipped = self.flipped[:-2]

            elif event.type == pygame.MOUSEBUTTONUP:
               if len(self.flipped) > 0 and len(self.flipped) % 2 == 0:
                  tileA, tileB = self.flipped[-1], self.flipped[-2] 
                  if tileA.image != tileB.image:
                     tileA.flip, tileB.flip = False, False
                     self.flipped = self.flipped[:-2]           
               for row in self.grid:
                  for tile in row:
                     if tile.rect.collidepoint(event.pos) and not tile.flip:
                        tile.flip = True
                        self.flipped.append(tile)

               if len(self.flipped) > 0 and len(self.flipped) % 2 == 0:
                  pygame.time.set_timer(timer_id, 2000) # 2 seconds
               else:
                  pygame.time.set_timer(timer_id, 0)

这篇关于统计图像数量并比较相似度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆