user12561688
user12561688

Reputation:

Why is event always pygame.MOUSEBUTTONDOWN in this situation?

I am on the final part of a massive project for school. I am creating a game of simon, where you must memorize colours and click them in the proper order.

After my animations for the squares flash, I have 'usergottaclick' set to true.

if other == True:
 #And if event = Mousebuttondown
            if usergottaclick == False:
                if mousex >= 50 and mousex <= 150 and mousey >= 110 and mousey <= 160:
                    randomnum = random.randint(1,4)
                    addtosimons()

                    for i in range (0, roundnum):

                        if simonslist[i] == 1:
                            #Flashes red square

                        if simonslist[i] == 2:
                            #Flashes blue square

                        if simonslist[i] == 3:
                            #Flashes green square

                        if simonslist[i] == 4:
                            #Flashes yellow square

                    addroundnum()
                    usergottaclick = True

This is my code for when it is the users turn to click the squares:

def usersturn():
#This code is under if event = pygame.MOUSEBUTTONDOWN
global usergottaclick
if usergottaclick == True:
    playerchoicelist = []
    for i in range (0, roundnum -1 ):

        if mousex >=200 and mousex <= 600 and mousey >= 0 and mousey <= 375:
            clicknum = 1
            playerchoicelist.append(clicknum)
            pygame.draw.rect(screen, REDLIGHT, [200, 0, 400, 375])
            pygame.display.update()
            pygame.time.delay(500)
            if playerchoicelist[i] != simonslist[i]:
                print("Wrong")
                changeusergottaclick()
                subtractroundnum()

        if mousex >=600 and mousex <= 1000 and mousey >= 0 and mousey <= 375:
            clicknum = 2
            playerchoicelist.append(clicknum)
            pygame.draw.rect(screen, BLUELIGHT, [600, 0, 400, 375])
            pygame.display.update()
            pygame.time.delay(500)
            if playerchoicelist[i] != simonslist[i]:
                print("Wrong")
                changeusergottaclick()
                subtractroundnum()

        if mousex >=200 and mousex <= 600 and mousey >= 375 and mousey <= 750:
            clicknum = 3
            playerchoicelist.append(clicknum)
            pygame.draw.rect(screen, GREENLIGHT, [200, 375, 400, 375])
            pygame.display.update()
            pygame.time.delay(500)
            if playerchoicelist[i] != simonslist[i]:
                print("Wrong")
                changeusergottaclick()
                subtractroundnum()


        if mousex >=600 and mousex <= 1000 and mousey >= 375 and mousey <= 750:
            clicknum = 4
            playerchoicelist.append(clicknum)
            pygame.draw.rect(screen, YELLOWLIGHT, [600, 375, 400, 375])
            pygame.display.update()
            pygame.time.delay(500)
            if playerchoicelist[i] != simonslist[i]:
                print("Wrong")
                changeusergottaclick()
                subtractroundnum()




        else:
            changeusergottaclick()

What you need to focus on is the fact that the square the user clicks is added on to playerchoicelist.

But when I run this, it is acting as if event is always pygame.mousebuttondown , and just clicks the square as many times as the loop allows it to (as many times as roundnum is set to).

How do i get it so that they can only click one square at a time, then have to click again to click another?

Thank you so much to whoever helps, this is for my mark.

Upvotes: 1

Views: 80

Answers (1)

Kingsley
Kingsley

Reputation: 14906

The code seems to be trying to "drive" the user, rather than simply reacting to clicks when they happen. There isn't roundnum player mouse-events, there is typically one at a time. Process each event as it happens.

In an event-driven program (i.e.: 99% of all pygame programs), it's usually a good idea to process these as real-time events, and use the system time to determine when things need to happen in the future. This allows the code to not use pygame.time.delay(), and gives a much better flow to the user-interface.

The code below draws your "simon" rectangles, using a simple list-of-lists data structure to hold each rectangle, it's name, colours and the time when it was last clicked. Keeping all your rectangle data in a list like this allows the program to loop over the list performing the same code for every button. Less code is less chance of mistakes, and make the code simpler and cleaner. Whenever you find yourself copying code blocks, and then making simple modifications, it's better to stop for a minute and wonder if there isn't a better way. Keeping a pygame Rect object also allows you to do simple collision detection.

So button's time-field (initially zero) is used to determine if the rectangle needs to be drawn in the base-colour or highlight-colour. When the button is clicked, the current time is stored in the button. When the button is then drawn to the screen, if it's still LIGHT_TIME milliseconds since the click, it's drawn highlighted.

import pygame

pygame.init()

WINDOW_WIDTH  = 1000
WINDOW_HEIGHT = 1000
FPS = 60 

RED         = ( 200,   0,   0 )
BLUE        = (   0,   0, 200 )
YELLOW      = ( 200, 200,   0 )
GREEN       = (   0, 200,   0 )
LIGHTRED    = ( 255,   0,   0 )
LIGHTBLUE   = (   0,   0, 255 )
LIGHTYELLOW = ( 255, 255,   0 )
LIGHTGREEN  = (   0, 255,   0 )

LIGHT_TIME   = 300 # milliseconds the button stays hghlighted for

# define the on-screen button areas & colour
#              name      base    pressed    click   rectangle
#                        colour  colour     time    
buttons = [  [ "red",    RED,    LIGHTRED,    0,    pygame.Rect( 200, 0, 400, 375 )   ],
             [ "blue",   BLUE,   LIGHTBLUE,   0,    pygame.Rect( 600, 0, 400, 375 )   ],
             [ "green",  GREEN,  LIGHTGREEN,  0,    pygame.Rect( 200, 375, 400, 375 ) ],
             [ "yellow", YELLOW, LIGHTYELLOW, 0,    pygame.Rect( 600, 375, 400, 375 ) ]  ]

# ---------- Main ----------

screen = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ) )
clock  = pygame.time.Clock()
game_over = False
while not game_over:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            game_over = True
        elif ( event.type == pygame.MOUSEBUTTONUP ):
            mouse_pos = event.pos
            for i, b in enumerate( buttons ):                                 # for every button
                name, base_colour, pressed_colour, click_time, butt_rect = b  #   get the button's parts
                if ( butt_rect.collidepoint( mouse_pos ) ):                   #   was the mouse-click inside this?
                    print( "Button [" + name + "] pressed" )
                    buttons[i][3] = pygame.time.get_ticks()                   # update the button's click-time


    time_now = pygame.time.get_ticks()                                        # get the current time (in milliseconds)
    for b in buttons:                                                         # for every button
        name, base_colour, pressed_colour, click_time, butt_rect = b          #   get the button's parts
        if ( click_time > 0 and click_time + LIGHT_TIME > time_now ):         #   if the mouse-click was LIGHT_TIME ms before time-now
            colour = pressed_colour  # light-up colour                        #       colour the button light
        else:                                                                 #   otherwise,
            colour = base_colour     # base colour                            #       colour the button normally
        pygame.draw.rect( screen, colour, butt_rect, 0 )                      #   draw a filled rectangle in the colour, for the button


    pygame.display.update()
    clock.tick(FPS)

pygame.quit()

Upvotes: 1

Related Questions