A pygame game is a loop. Each time around it the game does three things, then shows the result:
- Handle events: read what the player did (keys, mouse, the close button).
- Update: move things, apply the rules, check collisions.
- Draw: paint the new frame, then
flip()it onto the screen.
clock.tick(60) at the end holds the loop to 60 frames a second. Here are the three steps in a small game: a ball falls, and Space throws it back up.
Press Play, click the game, then press Space.
Why the order matters
Events first, so this frame reacts to what the player just did. If you read input after drawing, the game lags one frame behind the keyboard.
Update before draw, so the frame shows the new state. Drawing first would show where things were, not where they are.
Fill, draw, flip. Start each frame by clearing the screen (screen.fill), draw the background first and the player last (later drawings cover earlier ones), and call pygame.display.flip() exactly once at the end. Pygame draws into a hidden buffer; the window shows nothing new until the flip.
Reading events every frame
The for event in pygame.event.get() loop does more than notice keys. It also tells the operating system that your window is alive. A loop that never calls pygame.event.get() (or pygame.event.pump()) gets a "Not Responding" window on Windows and a spinning cursor on macOS, and the close button stops working. Keep the event loop even in a program that ignores input.
Ending the loop
The running flag is the usual way to stop: the QUIT event sets it to False, the loop finishes its pass, and pygame.quit() runs after it. A game can also end the loop from its own rules, for example when the player presses Escape:
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
running = False
Avoid calling pygame.quit() inside the loop. The loop would carry on to screen.fill() with pygame shut down and stop with pygame.error: video system not initialized.
A game class
As a game grows, the loop is easier to read as a class with one method per step. The structure is the same:
keys[pygame.K_RIGHT] - keys[pygame.K_LEFT] is a short way to get 1, -1 or 0 for the direction, because a pressed key counts as True (1).
Next
Pygame Clock explains tick(), frame rates and delta time, and Pygame events covers everything the event loop can read.
Frequently Asked Questions
What is a game loop in pygame?
A while loop that runs once per frame. Each pass reads the player's input with pygame.event.get(), updates positions and rules, draws everything, shows the frame with pygame.display.flip() and waits with clock.tick(60).
What is the difference between display.flip() and display.update()?
flip() shows the whole screen. update() with no arguments does the same; update(rect_list) shows only those parts of the screen, which can be faster for games that change little. For most games flip() is the simple choice.
Why does my pygame window freeze or say Not Responding?
The loop is not reading events. Call pygame.event.get() (or pygame.event.pump()) every frame, or the operating system decides the window has stopped responding.