Unit 12.2A · Term 2

Game Loop

The game loop is the heartbeat of every game. It runs continuously — handling events, updating state, and rendering visuals — dozens of times per second.

Learning Objectives

  • 12.5.1.3 Code the game loop of the application

Lesson Presentation

12.2A-game-loop.pdf · Slides for classroom use

Conceptual Anchor

The Film Projector Analogy

A movie projector shows 24 frames per second — each frame is a still image, but played fast they create the illusion of motion. A game loop does the same: clear screen → draw new frame → show it → repeat. The faster this cycle runs (FPS), the smoother the game feels.

Rules & Theory

The 3 Phases of a Game Loop

Phase What Happens Code
1. Handle Events Process user input (keys, mouse, quit) pygame.event.get()
2. Update State Move objects, check collisions, update scores Game logic code
3. Render (Draw) Clear screen, draw everything, display screen.fill() + draw + flip()

FPS Control with Clock

Command Purpose
clock = pygame.time.Clock() Create a Clock object
clock.tick(60) Limit loop to 60 FPS maximum
clock.get_fps() Get actual frames per second

Event Types

Event When It Fires
pygame.QUIT User clicks the window close button (✕)
pygame.KEYDOWN A key is pressed down
pygame.KEYUP A key is released
pygame.MOUSEBUTTONDOWN A mouse button is pressed
pygame.MOUSEMOTION The mouse is moved

Worked Examples

1 Standard Game Loop Template

import pygame import sys pygame.init() # --- Setup --- WIDTH, HEIGHT = 800, 600 FPS = 60 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Game Loop Demo") clock = pygame.time.Clock() # --- Colors --- BLACK = (0, 0, 0) WHITE = (255, 255, 255) # --- Game Loop --- running = True while running: # Phase 1: HANDLE EVENTS for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: running = False # Phase 2: UPDATE STATE # (game logic goes here) # Phase 3: RENDER screen.fill(BLACK) # (draw objects here) pygame.display.flip() # Control FPS clock.tick(FPS) pygame.quit() sys.exit()

2 Showing FPS Counter

import pygame, sys pygame.init() screen = pygame.display.set_mode((800, 600)) pygame.display.set_caption("FPS Counter") clock = pygame.time.Clock() font = pygame.font.SysFont("Arial", 24) running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False screen.fill((30, 30, 30)) # Display current FPS fps_text = font.render(f"FPS: {clock.get_fps():.0f}", True, (0, 255, 0)) screen.blit(fps_text, (10, 10)) pygame.display.flip() clock.tick(60) pygame.quit() sys.exit()

Common Pitfalls

No clock.tick() = Unlimited Speed

Without clock.tick(), the loop runs as fast as the CPU allows. This wastes power, heats the CPU, and makes game speed inconsistent across different computers.

Drawing BEFORE Filling

Always screen.fill() FIRST, then draw objects. If you draw first and then fill, your drawings get covered!

Tasks

Remember

Name the 3 phases of a game loop and describe what happens in each.

Apply

Write a game loop that changes the background color when the user presses the Space bar.

Apply

Add an FPS counter to any PyGame application displaying current frames per second.

Self-Check Quiz

Q1: What are the 3 phases of a game loop?

1) Handle Events — process user input. 2) Update State — move objects, check collisions. 3) Render — clear screen, draw, display.

Q2: What does clock.tick(60) do?

Limits the game loop to a maximum of 60 iterations per second (60 FPS), ensuring consistent speed and preventing CPU waste.

Q3: What event type is triggered when the user clicks ✕?

pygame.QUIT