我正在做一个记忆游戏,但我无法让程序检查瓷砖是否匹配,如果匹配,则瓷砖保持暴露状态,如果瓷砖不匹配,则将瓷砖暴露一秒钟。第116-122行我认为程序的该部分应该进行检查,但对于is_matching()绝不会返回true。我觉得我应该检查实际的瓦片本身是否彼此相等,但是对我来说,这似乎适得其反,因为瓦片只是网格上的一个位置,图像是在瓦片上绘制的?
提前致谢
# Code Example 2
#
import pygame
import random
import time
# 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('Tic Tac Toe')
# 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
# === objects that are part of every game that we will discuss
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
# === game specific objects
self.board = []
self.score = [0]
self.board_size = 4
self.create_board()
self.click = 0
self.exposed = 0
self.first_image= None
self.second_image= None
self.tile1 = None
self.tile2 = None
self.match = None
def create_board(self):
Tile.set_surface(self.surface)
# width = self.surface.get_width()//self.board_size
# height = self.surface.get_height() // self.board_size
# image is of type surface
self.images = []
new_image =['image1.bmp','image2.bmp','image3.bmp','image4.bmp', 'image5.bmp','image6.bmp','image7.bmp',
'image8.bmp','image1.bmp','image2.bmp','image3.bmp','image4.bmp', 'image5.bmp','image6.bmp',
'image7.bmp','image8.bmp']
for file_name in new_image:
image = pygame.image.load(file_name)
self.images.append(image)
# random.shuffle(self.images)
cover = pygame.image.load('image0.bmp')
#image1 = pygame.image.load(images_list)
width = image.get_width()
height = image.get_height()
for row_index in range(0, self.board_size):
row = []
for col_index in range(0, self.board_size):
x = width * col_index
y = height * row_index
imageindex = row_index * self.board_size + col_index
image = self.images[imageindex]
tile = Tile(x,y,image,cover)
row.append(tile)
self.board.append(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.MOUSEBUTTONUP and self.continue_game == True:
self.handle_mouse_up(event)
def update(self):
# Update the game objects for the next frame.
# - self is the Game to update
self.score[0] = pygame.time.get_ticks() // 1000
if self.first_image != None and self.match:
print(self.check_matching())
self.first_image = None
self.tile1 = None
self.second_image = None
self.tile2 = None
self.exposed += 1
print(self.exposed)
if self.first_image != None:
if self.second_image != None and not self.match:
# time.sleep(1)
print(self.check_matching())
self.tile1.hide_tile()
self.tile2.hide_tile()
self.second_image = None
self.tile2 = None
self.first_image = None
self.tile1 = None
def handle_mouse_up(self,event):
for row in self.board:
for tile in row:
valid_click = tile.select(event.pos)
if valid_click == True:
# self.number_exposed += 1
# time.sleep(1)
tile.expose_tile()
print(self.click)
if self.click == 0:
self.first_image = tile.image
self.tile1 = tile
elif self.click == 1:
self.second_image = tile.image
self.tile2 = tile
self.click += 1
print(self.first_image)
print(self.second_image)
if self.click > 1:
self.click = 0
def draw(self):
# Draw all game objects.
# - self is thae Game to draw
# draw tiles
self.surface.fill(self.bg_color) # clear the display surface first
for each_row in self.board:
for each_tile in each_row:
each_tile.draw()
self.draw_score()
pygame.display.update() # make the updated surface appear on the display
def draw_score(self):
# 1. Set the color
size = self.surface.get_width()
fg_color = pygame.Color('white')
# 2.create the font object
font = pygame.font.SysFont('', 70)
# 3 Create a text box by rendering the font
text_string = '' + str(self.score[0])
text_box = font.render(text_string, True, fg_color, self.bg_color)
surface_height = self.surface.get_width()
text_box_height = text_box.get_width()
location = (surface_height - text_box_height, 0)
# 4 Compute the location of the text box
#location = (430, 0)
# 5 Blit or pin the text box on the surface
self.surface.blit(text_box, location)
def decide_continue(self):
if self.exposed >= 1:
self.continue_game = False
def check_matching(self):
self.match = self.first_image == self.second_image
return self.match
# Check and remember if the game should continue
# - self is the Game to check
class Tile:
surface = None
border_size = 3
border_color = pygame.Color('black')
# An object in this class represents a Dot that moves
@classmethod
def set_surface(cls,game_surface):
cls.surface = game_surface
# instance method
def __init__(self,x , y, image, cover):
self.image = image
self.cover = cover
self.covered = True
width = self.image.get_width()
height = self.image.get_height()
self.rect = pygame.Rect(x, y, width, height)
def draw(self):
pygame.draw.rect(Tile.surface,Tile.border_color,self.rect,Tile.border_size)
Tile.surface.blit(self.image,self.rect)
if self.covered:
Tile.surface.blit(self.cover, self.rect)
else:
Tile.surface.blit(self.image, self.rect)
# Draw the dot on the surface
# - self is the Dot
def select(self, position):
valid_click = False
if self.rect.collidepoint(position):
if self.covered:
valid_click = True
self.expose_tile()
else:
valid_click = False
return valid_click
def expose_tile(self):
# if a tile is clicked this method will show the picture underneath that tile
self.covered = False
def hide_tile(self):
self.covered = True
def __eq__(self, other_tile):
if self.first_image == other_tile.image:
return True
else:
return False
main()
最佳答案
这些图块不匹配,因为您实际要做的是比较图像对象:
self.match = self.first_image == self.second_image
但每个图片会加载两次。为每个图像生成不同的对象,因此它们将永远不匹配。
加载每个图像一次,并将其用于2个匹配的图块:
# define unique image names
new_image =['image1.bmp','image2.bmp','image3.bmp','image4.bmp',
'image5.bmp','image6.bmp','image7.bmp','image8.bmp']
# load each unique image
for file_name in new_image:
image = pygame.image.load(file_name)
self.images.append(image)
# create a list where each loaded image object is used twice
self.images = self.images + self.images
此外,由于图像名称的编号有所不同,因此可以简化名称列表的定义:
new_image = ['image' + str(i) + '.bmp' for i in range(1,9)]
扩展按赞
那时间延迟呢
完全删除
self.first_image
和self.second_image
。适应Tile
:class Tile:
# [...]
def __eq__(self, other_tile):
return self.image == other_tile.image
单击磁贴后,将其保留在
self.tile1
和self.tile2
中。第一次单击时,如果不匹配,则隐藏暴露的图块:if self.click == 0:
if self.tile1 != self.tile2:
if self.tile1:
self.tile1.hide_tile()
if self.tile2:
self.tile2.hide_tile()
第二次点击时,请设置必须自动覆盖的时间(例如
pygame.time.get_ticks() + 2000
):elif self.click == 1:
self.tile2 = tile
self.hide_time = pygame.time.get_ticks() + 2000
评估是否必须在
update
中覆盖图块:ticks = pygame.time.get_ticks()
if self.tile1 and self.tile2:
if self.tile1 != self.tile2 and self.hide_time > 0 and ticks > self.hide_time:
self.tile1.hide_tile()
self.tile2.hide_tile()
更改您的代码:
class Game:
def __init__(self, surface):
# [...]
self.hide_time = 0
# [...]
def update(self):
ticks = pygame.time.get_ticks()
self.score[0] = ticks // 1000
if self.tile1 and self.tile2:
if self.tile1 != self.tile2 and self.hide_time > 0 and ticks > self.hide_time:
self.tile1.hide_tile()
self.tile2.hide_tile()
def handle_mouse_up(self,event):
self.hide_time = 0
if self.click == 0:
if self.tile1 != self.tile2:
if self.tile1:
self.tile1.hide_tile()
if self.tile2:
self.tile2.hide_tile()
tiles = [t for row in self.board for t in row if t.select(event.pos) and not t.covered]
if any(tiles):
tile = tiles[0]
if self.click == 0:
self.tile1 = tile
elif self.click == 1:
self.tile2 = tile
self.hide_time = pygame.time.get_ticks() + 2000
tile.expose_tile()
self.click += 1
if self.click > 1:
self.click = 0
# [...]
def check_matching(self):
self.match = self.tile1.image == self.tile2.image
return self.match