Retceps
Retceps

Reputation: 23

Pygame event overriding

I'm struggling with my button class's functionality. The issue I suspect lies in the pygame.event check. When I press the escape button, it should close python if on the main menu or go back to the main menu if in one of the screens. This works perfectly fine; however, if I hover my cursor over the buttons and try to do the same thing, it sometimes takes anywhere between 1-8 presses of the button in order to do this. I suspect it's because one of the pygame.event checks overrides the other, but I'm struggling to rewrite it in a way that will register both.

class button():
    def __init__(self, color, x, y, width, height, text = ''):
           self.color = color
           self.x = x
           self.y = y
           self.width = width
           self.height = height
           self.text = text

    def draw(self, screen):
        button = pygame.draw.rect(screen, self.color, (self.x - self.width/2, self.y - self.height/2, self.width, self.height)) #Draws button

        font = pygame.font.SysFont('Calibri body', 70)
        text = font.render(self.text, 1, (255,255,255)) #Renders text
        textrect = text.get_rect() #Gets rectangle of text
        textrect.center = (self.x, self.y) #Assigns center coordinates of text
        screen.blit(text, textrect) #Pastes result
        
        mx, my = pygame.mouse.get_pos() #Gets mouse coordinates
        if button.collidepoint(mx, my): #Checks if mouse coordinates match to button
            for event in pygame.event.get():
                if event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        running = False
                if event.type == MOUSEBUTTONDOWN and event.button ==1:
                        return(True)

def mainMenu():
    running = True
    while running:
        screen.blit(mainBackground,(0,0)) 
        draw_text('Obstacle race', font1, (255, 255, 255), screen, width/2, height/15) #Creates main title text

        levelSelector_button = button((220, 220, 220), width/2, height/2-150, 400, 100, 'Level Selector')
        if levelSelector_button.draw(screen): #Draws button and checks for true
            levelSelector()

        leaderboard_button = button((220, 220, 220), width/2, height/2, 400, 100, 'Leaderboard')
        if leaderboard_button.draw(screen): #Draws button and checks for true
            leaderboard()
    
        instructions_button = button((220, 220, 220), width/2, height/2+150, 400, 100, 'Instructions')
        if instructions_button.draw(screen): #Draws button and checks for true
            instructions()

        settings_button = button((220, 220, 220), width/2, height/2+300, 400, 100, 'Settings')
        if settings_button.draw(screen):#Draws button and checks for true
            settings()

        #Event check
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()

        pygame.display.update() 
        mainClock.tick(60) #Caps framerate at 60fps

Upvotes: 0

Views: 133

Answers (1)

Rabbid76
Rabbid76

Reputation: 211258

See pygame.event.get():

This will get all the messages and remove them from the queue. [...]

This means that if pygame.event.get() is called in multiple event loops, only one loop will receive the events, but never all loops will receive all events and some events will seem to be missed. You must fetch the events once per frame and use them in multiple loops or pass the list of events to functions and methods where they are used:

# application loop
while True:

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

    # use list of events
    for event in event_list :
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        # [...]


    # pass list of events to a method
    some_method(event_list)

    # [...]

Note that if event_list is a variable in the global namespace, that variable can be used in any function or method to get the events.

Upvotes: 1

Related Questions