记忆游戏不匹配图块 - python

我正在做一个记忆游戏,但我无法让程序检查瓷砖是否匹配,如果匹配,则瓷砖保持暴露状态,如果瓷砖不匹配,则将瓷砖暴露一秒钟。第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_imageself.second_image。适应Tile

class Tile:

    # [...]
    def __eq__(self, other_tile):
        return self.image == other_tile.image

单击磁贴后,将其保留在self.tile1self.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

python中类初始化的最佳实践 - python

嗨,我想知道最佳实践是在python中初始化类,同时确保我的属性具有正确的数据类型。我应该使用默认值初始化类属性还是调用检查功能?class Foo: # Call with default value def __init__(self, bar=""): self._bar = bar # Calling set-function d…

Python __getitem__和in运算符导致奇怪的行为 - python

是什么解释了以下行为:class Foo: def __getitem__(self, item): print("?") return 1 f = Foo() 1 in f # prints one ? and returns True 5 in f # prints ? forever until you raise a Keyboa…

如何使用pass语句? - python

我正在学习Python,并且已经到达有关pass语句的部分。我正在使用的指南将其定义为通常用作占位符的Null语句。我仍然不完全明白那是什么意思。有人可以告诉我一个简单的/基本情况,在其中使用pass语句以及为什么需要它吗? 参考方案 假设您正在使用尚未实现的某些方法设计一个新类。class MyClass(object): def meth_a(self)…

子类化C模块中定义的类型时,方法将被忽略 - python

我将在C模块中定义的类型作为子类,以别名某些属性和方法,以便我的脚本在不同的上下文中工作。为了使它起作用,我必须手动调整班级字典吗?如果我没有在字典中添加对DistanceTo的引用,则会得到Point3d has no attribute named DistanceTo。class Point3d(App.Base.Vector): def __new_…

Python TypeError:“类型”对象不支持项目分配 - python

我必须设计并实现一个TwoSum类。它应该支持以下操作:add-将数字添加到内部数据结构中。find-查找是否存在任何一对数字,其总和等于该值。这是我的代码:class TwoSum(object): dict = {} def add(self,n): dict[n] = n #TypeError: 'type' object does…