1

I've created a button function and it works, but if I use the function more than once on the screen then it will only work on one of the buttons and I'm not sure why.

Here is the code for the button function.

def button(x, y, w, h, action=None):

    mx, my = pygame.mouse.get_pos()

    for event in pygame.event.get():

        if x + w > mx > x and y + h > my > y:
            if event.type == pygame.MOUSEBUTTONDOWN:
                action()

and here is the code where I am trying to use it, the first button which makes it start the game_loop works but the button which should quit doesn't

def game_intro():

    intro = True

    while intro:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        gameDisplay.blit(bg_resize,(0,0))
        gameDisplay.blit(play_resize,(100,150))
        gameDisplay.blit(quit_resize,(575,150))
                         

        button(100,150,393,393,game_loop)
        button(575,150,393,393,quit)


  
        pygame.display.flip()
        clock.tick(15)
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
jrsevans
  • 47
  • 5

1 Answers1

0

The issue is, that you have multiple event loops. pygame.event.get() get all the messages and remove them from the queue. If pygame.event.get () is called in multiple event loops, only one loop receives the events, but never all loops receive all events. As a result, some events appear to be missed.

Get the events once in the application loop and pass the list of events (event_list) to the button function.
Furthermore, in case of a mosue event (e.g. MOUSEBUTTONDOWN) the current mouse position is stored in the pos attribute of the pygame.event.Event object (see pygame.event module):

def button(x, y, w, h, event_list, action=None):

    for event in event_list:
       
        if event.type == pygame.MOUSEBUTTONDOWN:
            mx, my = event.pos
            if x + w > mx > x and y + h > my > y:
                action()
def game_intro():
    intro = True
    while intro:

        event_list = pygame.event.get() # get list of events only once

        for event in event_list:
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

    # [...]

    button(100, 150, 393, 393, event_list, game_loop)
    button(575, 150, 393, 393, event_list, quit)

    # [...]
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Not sure if it is something I am doing wrong but when I put `event_list = pygame.event.get():` it says there is a syntax error on the : – jrsevans Oct 22 '20 at 14:51
  • Ah awesome ok, althought it is now coming up as an error saying for event in event_list: TypeError: 'function' object is not iterable – jrsevans Oct 22 '20 at 14:58
  • Sorry I'm still quite new to this so probably making simple mistakes. I've added it to the function `def button(x, y, w, h, event_list, action=None)` and called it with the buttons `button(100,150,393,393, event_list, game_loop)` but still get the same error – jrsevans Oct 22 '20 at 15:24
  • 1
    yep, I hadn't update all the calls of the function. Thank you for the help – jrsevans Oct 22 '20 at 16:25
  • @jrsevans Thank you. You're welcome. – Rabbid76 Oct 23 '20 at 15:56