记忆游戏不匹配瓷砖 [英] Memory game not matching tiles

查看:37
本文介绍了记忆游戏不匹配瓷砖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个记忆游戏,我无法让程序检查瓷砖是否匹配,如果它们匹配,则让瓷砖保持暴露状态,如果瓷砖不匹配,则保持瓷砖暴露一秒钟.第 116-122 行我认为程序的一部分应该检查但它永远不会为 is_matching() 返回 true.我觉得我应该检查实际的瓷砖本身是否彼此相等,但对我来说,这似乎适得其反,因为瓷砖只是网格上的一个位置,而图像是在瓷砖上绘制的?提前致谢

# 代码示例 2#导入pygame随机导入导入时间# 用户自定义函数定义主():# 初始化所有pygame模块(有些需要初始化)pygame.init()# 创建一个pygame显示窗口pygame.display.set_mode((500, 400))# 设置显示窗口的标题pygame.display.set_caption('井字游戏')# 获取显示面w_surface = pygame.display.get_surface()# 创建一个游戏对象游戏 = 游戏(w_surface)# 通过调用游戏对象上的 play 方法开始主游戏循环游戏.play()# 退出pygame并清理pygame窗口pygame.quit()# 用户定义的类课堂游戏:# 这个类中的一个对象代表一个完整的游戏.def __init__(self,surface):# 初始化游戏.# - self 是要初始化的游戏# - 表面是显示窗口表面对象# === 对象是我们将讨论的每个游戏的一部分self.surface = 表面self.bg_color = pygame.Color('黑色')self.FPS = 60self.game_Clock = pygame.time.Clock()self.close_clicked = Falseself.continue_game = True# === 游戏特定对象self.board = []self.score = [0]self.board_size = 4self.create_board()self.click = 0自我暴露 = 0self.first_image= 无self.second_image= 无self.tile1 = 无self.tile2 = 无self.match = 无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# 图像是表面类型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']对于 new_image 中的 file_name:图像 = 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)宽度 = image.get_width()高度 = image.get_height()对于范围内的 row_index(0,self.board_size):行 = []对于范围内的 col_index(0,self.board_size):x = 宽度 * col_indexy = 高度 * row_indeximageindex = row_index * self.board_size + col_index图像 = self.images[图像索引]瓷砖 = 瓷砖(x,y,图像,封面)row.append(tile)self.board.append(row)定义播放(自我):# 玩游戏直到玩家按下关闭框.# - self 是应该继续与否的游戏.while not self.close_clicked: # 直到玩家点击关闭框# 播放帧self.handle_events()self.draw()如果 self.continue_game:自我更新()self.decide_continue()self.game_Clock.tick(self.FPS) # 最多以每秒 FPS 帧数运行def handle_events(self):# 通过适当地改变游戏状态来处理每个用户事件.# - self 是将处理其事件的游戏事件 = pygame.event.get()对于事件中的事件:如果 event.type == pygame.QUIT:self.close_clicked = True如果 event.type == pygame.MOUSEBUTTONUP 和 self.continue_game == True:self.handle_mouse_up(事件)定义更新(自我):# 更新下一帧的游戏对象.# - self 是要更新的游戏self.score[0] = pygame.time.get_ticks()//1000如果 self.first_image != None 和 self.match:打印(self.check_matching())self.first_image = 无self.tile1 = 无self.second_image = 无self.tile2 = 无自我暴露 += 1打印(自我曝光)如果 self.first_image != 无:如果 self.second_image != None 而不是 self.match:# time.sleep(1)打印(self.check_matching())self.tile1.hide_tile()self.tile2.hide_tile()self.second_image = 无self.tile2 = 无self.first_image = 无self.tile1 = 无def handle_mouse_up(self,event):对于 self.board 中的行:对于行中的瓷砖:valid_click = tile.select(event.pos)如果 valid_click == True:# self.number_exposed += 1# time.sleep(1)tile.expose_tile()打印(self.click)如果 self.click == 0:self.first_image = tile.imageself.tile1 = 瓷砖elif self.click == 1:self.second_image = tile.imageself.tile2 = 瓷砖self.click += 1打印(self.first_image)打印(self.second_image)如果 self.click >1:self.click = 0定义绘制(自我):# 绘制所有游戏对象.# - self 是要绘制的游戏# 绘制瓷砖self.surface.fill(self.bg_color) # 先清空显示面对于 self.board 中的 each_row:对于 each_row 中的 each_tile:each_tile.draw()self.draw_score()pygame.display.update() # 使更新的表面出现在显示器上def draw_score(self):# 1.设置颜色大小 = self.surface.get_width()fg_color = pygame.Color('白色')# 2.创建字体对象font = pygame.font.SysFont('', 70)# 3 通过渲染字体创建一个文本框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()位置 = (surface_height - text_box_height, 0)# 4 计算文本框的位置#location = (430, 0)# 5 Blit 或 pin 文本框在表面上self.surface.blit(text_box, location)定义决定_继续(自我):如果 self.exposed >= 1:self.continue_game = Falsedef check_matching(self):self.match = self.first_image == self.second_image返回 self.match# 检查并记住游戏是否应该继续# - self 是要检查的游戏类瓷砖:表面 = 无边框尺寸 = 3border_color = pygame.Color('黑色')# 这个类中的一个对象代表一个会移动的点@类方法def set_surface(cls,game_surface):cls.surface = game_surface# 实例方法def __init__(self,x, y, image, cover):self.image = 图像self.cover = 封面self.covered = 真宽度 = self.image.get_width()高度 = self.image.get_height()self.rect = pygame.Rect(x, y, 宽度, 高度)定义绘制(自我):pygame.draw.rect(Tile.surface,Tile.border_color,self.rect,Tile.border_size)Tile.surface.blit(self.image,self.rect)如果自我覆盖:Tile.surface.blit(self.cover, self.rect)别的:Tile.surface.blit(self.image, self.rect)# 在曲面上画点# - self 是点定义选择(自我,位置):valid_click = 假如果 self.rect.collidepoint(position):如果自我覆盖:valid_click = 真self.expose_tile()别的:valid_click = 假返回 valid_clickdefexpose_tile(self):# 如果一个图块被点击,这个方法将显示该图块下面的图片self.covered = 假def hide_tile(self):self.covered = 真def __eq__(self, other_tile):如果 self.first_image == other_tile.image:返回真别的:返回错误主要的()

解决方案

tiles 不匹配,因为你实际上做的是比较图像对象:

<块引用>

self.match = self.first_image == self.second_image

但每个图像都加载了两次.因为每张图片都是针对不同的对象生成的,所以它们永远不会匹配.

加载每个图像一次并将其用于 2 个匹配的图块:

# 定义唯一的图像名称new_image =['image1.bmp','image2.bmp','image3.bmp','image4.bmp','image5.bmp','image6.bmp','image7.bmp','image8.bmp']# 加载每个唯一的图像对于 new_image 中的 file_name:图像 = pygame.image.load(file_name)self.images.append(image)# 创建一个列表,其中每个加载的图像对象被使用两次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):返回 self.image == other_tile.image

点击磁贴后,将它们保留在 self.tile1self.tile2 中.当第一次点击发生时,隐藏暴露的瓷砖,如果它们不匹配:

if self.click == 0:如果 self.tile1 != self.tile2:如果 self.tile1:self.tile1.hide_tile()如果 self.tile2:self.tile2.hide_tile()

当第二次点击发生时,设置它们必须被自动覆盖的时间(例如 pygame.time.get_ticks() + 2000):

elif self.click == 1:self.tile2 = 瓷砖self.hide_time = pygame.time.get_ticks() + 2000

评估是否必须在 update 中覆盖图块:

ticks = pygame.time.get_ticks()如果 self.tile1 和 self.tile2:if self.tile1 != self.tile2 and self.hide_time >0 和刻度 >self.hide_time:self.tile1.hide_tile()self.tile2.hide_tile()

对代码的更改:

class 游戏:def __init__(self,surface):# [...]self.hide_time = 0# [...]定义更新(自我):滴答 = pygame.time.get_ticks()self.score[0] = ticks//1000如果 self.tile1 和 self.tile2:if self.tile1 != self.tile2 and self.hide_time >0 和刻度 >self.hide_time:self.tile1.hide_tile()self.tile2.hide_tile()def handle_mouse_up(self,event):self.hide_time = 0如果 self.click == 0:如果 self.tile1 != self.tile2:如果 self.tile1:self.tile1.hide_tile()如果 self.tile2:self.tile2.hide_tile()瓷砖 = [t for row in self.board for t in row if t.select(event.pos) and not t.covered]如果有(瓷砖):瓷砖 = 瓷砖 [0]如果 self.click == 0:self.tile1 = 瓷砖elif self.click == 1:self.tile2 = 瓷砖self.hide_time = pygame.time.get_ticks() + 2000tile.expose_tile()self.click += 1如果 self.click >1:self.click = 0# [...]def check_matching(self):self.match = self.tile1.image == self.tile2.image返回 self.match

I am making a memory game and I can't get the program to check if the tiles match and if they do match get the tiles to stay exposed, and keep the tiles exposed for one second if the tiles don't match. lines 116-122 I think that part of the program is supposed to check but it never returns true for is_matching(). I feel like I am supposed to check if the actual tiles themselves are equal to each other but to me, that seems counterproductive because the tile is just a location on the grid and the image is what's drawn on the tile?? thanks in advance

# 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()

解决方案

The tiles do not match, because what you actually do is to compare image objects:

self.match = self.first_image == self.second_image

but each image is loaded twice. For each image are generated to different objects, so they will never match.

Load each image once and use it for 2 matching tiles:

# 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

Furthermore, since the image names just differ in the number, the definition of the name list can be simplified:

new_image = ['image' + str(i) + '.bmp' for i in range(1,9)]


Extension according to the commend

what about the time delay

Completely remove self.first_image and self.second_image. Adapt Tile:

class Tile:

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

Once tiles have been clicked then keep them stated in self.tile1 and self.tile2. When the 1st click occurs, then hide the exposed tiles, if they do not match:

if self.click == 0:
    if self.tile1 != self.tile2:
        if self.tile1:
            self.tile1.hide_tile()
        if self.tile2:
            self.tile2.hide_tile()

When the 2nd click occurs then set the time (e.g. pygame.time.get_ticks() + 2000) when they have to be covered automatically:

elif self.click == 1:
    self.tile2 = tile
    self.hide_time = pygame.time.get_ticks() + 2000

Evaluate if the tiles have to be covered in 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()

Changes to your code:

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

这篇关于记忆游戏不匹配瓷砖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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