The Game Loop
Every real-time game (not just Asteroids) is built around one core idea: the game loop, an endless cycle that processes input, updates state, and draws the next frame, over and over, many times per second.
The three phases
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
running = True
while running:
# 1. Handle input/events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 2. Update game state
# (nothing to update yet)
# 3. Draw the frame
screen.fill((10, 10, 30)) # dark space background
pygame.display.flip()
clock.tick(60) # cap the loop at 60 frames per second
pygame.quit()
- Handle events:
pygame.event.get()drains the queue of everything that happened since the last frame (key presses, window close, etc). Without checking forpygame.QUIT, clicking the window's close button would do nothing. - Update: where you'll move the player, move asteroids, check collisions, this lesson's loop doesn't update anything yet, but the slot is there.
- Draw:
screen.fill(...)clears the previous frame to a solid color, thenpygame.display.flip()actually shows everything you've drawn since the last flip, nothing is visible on screen until you call it.
Why clock.tick(60)?
clock = pygame.time.Clock()
# ... inside the loop:
clock.tick(60)
clock.tick(60) pauses just long enough to cap the loop at 60 iterations per second. Without it, the loop would run as fast as the CPU allows, hundreds or thousands of times per second, burning a full CPU core and making movement speed depend on how fast the computer happens to be. Capping the frame rate keeps the game's speed consistent across different machines.
WARNING
Forgetting to call pygame.event.get() at all (not just skipping the QUIT check) makes the OS think the program has hung, since it isn't responding. Always drain the event queue every frame, even if you don't care about most of the events in it.