Purulence
Purulence

Reputation: 15

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

I am new to python and Pygame. I am trying to make a Schulte table game.

Here's what the game is doing:

  1. I have a 5 * 5 grid of total 25 pictures of numbers from 1-25. (5*5 Schulte grid)
  2. The number position is displayed in random order.
  3. When you tap the correct number's picture, the number changes color. When you click on the wrong number, a sound is played to indicate the wrong click, and the number does not change color. (Image changing colors or mouse click)
  4. There's a start button and the restart button.
  5. And finally, it displays the total elapsed time it took you to click all the numbers in order.

The program works as intended. Once a button is clicked, the colored number image is updated and a counter for each click is updated. But the problem is, if I click again on an already clicked number image, it keeps updating the counter.

For example, picture 1 is clicked, it turns red and now the click counter is 1. Then if I click again on the same picture 1, the program keep updating the counter. This way, if the counter reaches 25 even though I have not clicked all of the number pictures from 1-25 in order, the game will be over. I have tried to use pygame.event.set_allowed(pygame.MOUSEBUTTONDOWN), but it does not work(perhaps I don't know where in the loop to use it).

I am not sure where and how to exactly include this logic that the Mousebutton click will not update after a single click on the same picture. Please refer to the code below. Any help/tips is greatly appreciated. Thanks!

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)

Upvotes: 0

Views: 63

Answers (1)

Yannick - theSpy_007
Yannick - theSpy_007

Reputation: 271

The line if int(*list1[i-1]) <= zero: should be if int(*list1[i-1]) == zero:.

Upvotes: 2

Related Questions