统计图像数量并比较相似度 [英] Count images number and compared the similarity
问题描述
我正在编写一个名为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
属性.例如如果有 tileA
和 tileB
,那么如果 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屋!