0

I'm having trouble figuring out how the event loop should be polled in pygame when the application becomes a bit more complex than the basic tutorials.

The game has different phases (or states), and I need to check for different events in different states.

I have a Game class and a Player class. I am detecting keypresses for moving the player outside of the event queue, in order to achieve the desired behaviour. This is the simplified version of how the file is organised:

class Game:
    def __init__(self):
        self.state = self.intro
        self.player = Player()

    def intro(self):
        # Display the intro text, play some animations, music etc
        if pygame.key.get_pressed()[pygame.K_SPACE]:
            # Go to the next phase
            self.state = self.running

    def running(self):
        # Check player input
        if pygame.key.get_pressed()[pygame.K_d]:
            self.player.move_right()
        if pygame.key.get_pressed()[pygame.K_q]:
            self.player.move_left()
        if pygame.key.get_pressed()[pygame.K_z]:
            self.player.jump()

        # check game over
        if gameisover: # pseudo-variable
            self.state = self.gameover

    def gameover(self):
        # display gameover screen, wait for player input

    def run(self):
        self.state()

game = Game()

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

    game.run()            
    pygame.display.update()
    clock.tick(60)

The code that gets executed each frame (when Game.run() is called) depends on the phase of the game. This works, but it seems I have to check the event queue at each phase separately (including checking for quit events everywhere), otherwise pygame reports a crash to the OS.

If I check the event queue in a single loop only once, for each event I have to check the state the game is currently in before reacting to the event (suppose that SPACE does different things in different states).

I'm not sure of the best way to organise this in order to avoid checking the queue multiple times, but also avoid state checks and have each state only react to the events it's interested in.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Cirrocumulus
  • 520
  • 3
  • 15
  • What is the question? What is the error or what doesn't work as expected? – Rabbid76 Jul 25 '22 at 16:20
  • In the example above it happens only once, in the `while` loop. But if I try to do it a second time, e.g. in `Game.running()`, then at that point the event queue is empty (since it has just been emptied in the `while` loop) and therefore I can't handle any further events inside that function. I can only use `getpressed` events which are handled outside of the queue. The question is in the last paragraph... What is the best (or usual way) to check the event queue when using multiple game states? – Cirrocumulus Jul 25 '22 at 16:20
  • See [Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?](https://stackoverflow.com/questions/58086113/faster-version-of-pygame-event-get-why-are-events-being-missed-and-why-are/58087070#58087070) – Rabbid76 Jul 25 '22 at 16:23
  • Thank you. That was it. I didn't think of simply storing `pygame.event.get()` once and then just pass it around. Would you like to write an answer for that, or should I? Thanks a lot, in any case. – Cirrocumulus Jul 25 '22 at 21:16
  • No. This question is "duplicate" – Rabbid76 Jul 26 '22 at 04:51

0 Answers0