单击一次给定 area/image 后禁用 Pygame MOUSEBUTTONDOWN/UP 更新

Disable Pygame MOUSEBUTTONDOWN/UP update on a given area/image after it's clicked once

我是 python 和 Pygame 的新手。我正在尝试制作 Schulte table 游戏。

这是游戏正在做的事情:

  1. 我有一个 5 * 5 的网格,共有 25 张数字从 1 到 25 的图片。 (5*5 Schulte grid)
  2. 号码位置随机显示
  3. 当您点击正确号码的图片时,号码会改变颜色。当您点击错误的数字时,会播放提示错误点击的声音,并且数字不会改变颜色。 (Image changing colors or mouse click)
  4. 有开始按钮和重启按钮。
  5. 最后,它会显示您按顺序点击所有数字所花费的总时间。

该程序按预期运行。单击按钮后,彩色数字图像会更新,每次单击的计数器也会更新。但问题是,如果我再次点击已经点击过的数字图像,它会不断更新计数器。

例如,点击图片1,它变成红色,现在点击计数器为1。然后如果我再次点击同一张图片1,程序会不断更新计数器。这样,即使我没有按顺序点击所有1-25的数字图片,如果计数器达到25,游戏也会结束。我试过使用 pygame.event.set_allowed(pygame.MOUSEBUTTONDOWN),但它不起作用(也许我不知道在循环中的什么地方使用它)。

我不确定在何处以及如何准确地包含在单击同一图片后鼠标按钮单击不会更新的逻辑。请参考下面的代码。非常感谢任何 help/tips。谢谢!

import pygame  # import pygame library
import sys  # import sys library
import random  # import random library
import numpy as np  # import numpy library
import itertools  # Import the itertools library
import time  # import time library
# Initialize settings
pygame.init()  # Initialize pygame
size = width, height = 240, 320  # set the window size
screen = pygame.display.set_mode(size)  # display the window

pygame.display.set_caption("Schulte Grid")  # Give the window a name

# Image preparation
Xpts = [0, 48, 96, 144, 192]
Ypts = [0, 48, 96, 144, 192]
map = np.array(list(itertools.product(Xpts, Ypts)))  # 25 picture coordinates

# load sound
wavFileName = 'sounds/fire.wav'
sndTrack = pygame.mixer.music.load(wavFileName)
# Timer text preparation
myfont = pygame.font.SysFont('Comic Sans MS', 60)
GREEN = (0, 255, 0)
BLUE = (0, 0, 128)


def ready():
    global list1
    list1 = [[i] for i in range(25)]
    random.shuffle(list1)

# start interface


def start(start_page):
    while start_page:
        for event in pygame.event.get():  # Traverse all events
            if event.type == pygame.QUIT:  # if click to close the window, exit
                sys.exit()  # exit
            screen.blit(pygame.image.load(
                "pic/start-0.png"), (30, 190))  # show start screen
            global t_x, t_y
            t_x, t_y = pygame.mouse.get_pos()  # Get the position of the mouse
            if 30 <= t_x <= 200 and 190 <= t_y <= 250:  # 18*50 #Mouse over the picture
                screen.blit(pygame.image.load("pic/start-1.png"),
                            (30, 190))  # Get the mouse position and change color when moving to a certain position
            if event.type == pygame.MOUSEBUTTONDOWN and 30 <= t_x <= 200 and 190 <= t_y <= 250:
                start_page = False  # start page
                game_page = True  # game page
                global time_start  # Define the global variable to start timing

                time_start = time.time()  # timing
            pygame.display.flip()  # update all display

# game interface


def gamepage(game_page):
    # A variable is added here to make sure to start with the smallest number.
    zero = 0
    waiting_for_sleep_to_over = False
    # The status of the question interface, it is guaranteed that only one question will be generated.
    pic_zero = 1
    while game_page:
        while pic_zero:
            for i in range(25):  # must be 25 here
                screen.blit(pygame.image.load(
                    "pic/pic" + str(*list1[i - 1]) + ".png"), map[i])
            pic_zero = 0
        for event in pygame.event.get():  # Traverse all events
            if event.type == pygame.QUIT:  # if click to close the window, exit
                sys.exit()
            for i in range(25):
                # Determine the mouse position and whether it is pressed down. :
                if event.type == pygame.MOUSEBUTTONDOWN and map[i][0] <= event.pos[0] <= map[i][0] + 48 and map[i][1] <= event.pos[1] <= map[i][1] + 48:
                    # print(i)
                    if int(*list1[i-1]) <= zero:
                        screen.blit(pygame.image.load(
                            "pic/qic" + str(*list1[i-1]) + ".png"), map[i])  # Display the color map
                        # waiting_for_sleep_to_over = True
                        zero = zero + 1
                        # if event.type == pygame.MOUSEBUTTONDOWN and map[i][0] <= event.pos[0] <= map[i][0] + 48 and map[i][1] <= event.pos[1] <= map[i][1] + 48:
                        # waiting_for_sleep_to_over = FALSE
                        # pygame.event.set_blocked(pygame.MOUSEBUTTONDOWN)
                        # time.sleep(0.5)
                        # zero = zero
                        #     pygame.event.clear()
                        # pygame.event.set_allowed(pygame.MOUSEBUTTONDOWN)
                        print(zero)

                        if zero == 25:
                            time_end = time.time()  # end timing
                            time_c = round(
                                time_end - time_start, 2)  # time spent running
                            print('time cost:', int(time_c), 's')
                            textImage = myfont.render(
                                str(time_c) + 's', True, GREEN, BLUE)
                            screen.blit(textImage, (30, 250))
                            # screen.blit(pygame.image.load("pic/start-0.png"), (30, 210))
                            if event.type == pygame.MOUSEBUTTONDOWN and 30 <= t_x <= 210 and 200 <= t_y <= 250:
                                start_page = True
                                game_page = False
                            pygame.display.flip()  # update all display
                    else:
                        pygame.mixer.music.play()  # play music on error
            pygame.display.flip()  # update all display


# main loop
start_page = True
game_page = True
while True:
    ready()
    start(start_page)
    gamepage(game_page)

if int(*list1[i-1]) <= zero: 行应该是 if int(*list1[i-1]) == zero: