pyodide: loading…

[concept]Game Development with Pygame

Pygame Setup & Game Loop

# theory

pygame basics

Pygame is a Python library for making games. It handles the window, drawing, keyboard/mouse input, and timing. You basically get a blank canvas and Pygame gives you the tools to draw on it 60 times per second.

import pygame
pygame.init()

That's all you need to get started. Everything else builds on top.


from the videos

Pygame Install (2:09)

  • pip install pygame in terminal
  • import pygame at the top of your file
  • pygame.init() to initialize all modules
  • Testing with a simple window to confirm it works

Rectangles vs Vectors (5:39)

  • When to use pygame.Rect vs pygame.math.Vector2
  • Rects are great for collision detection and positioning
  • Vectors are better for physics and smooth movement
  • Gerber's advice: use Rect for position/collision, Vector2 for velocity/direction

Delta Time (3:48)

  • Frame-rate independent movement
  • Why 60fps on your machine != 60fps on another machine
  • The dt pattern that makes movement consistent everywhere

the game loop

Every game runs in a loop. It keeps going until the player quits. Each time through the loop is one "frame."

import pygame
pygame.init()

screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
running = True

while running:
    # 1. Handle events (keyboard, mouse, quit)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # 2. Update game state (move things, check collisions)
    # ... game logic goes here

    # 3. Draw everything
    screen.fill((0, 0, 0))  # black background
    pygame.display.flip()   # show the frame

    clock.tick(60)  # cap at 60 frames per second

pygame.quit()

Those three steps (handle events → update → draw) repeat every frame. That's the whole pattern.

delta time

This tripped me up at first. If you just do x += 5 every frame, your game runs at different speeds on different computers. A faster computer runs more frames per second, so things move faster. That's bad.

The fix is delta time (dt). It measures how long the last frame took:

clock = pygame.time.Clock()

while running:
    dt = clock.tick(60) / 1000.0  # dt in seconds (e.g., 0.016 for 60fps)

    # Now multiply ALL movement by dt
    x += velocity * dt  # consistent speed regardless of frame rate

Gerber tip: Always multiply velocity by dt. It's the difference between "5 pixels per frame" (inconsistent) and "300 pixels per second" (consistent on every machine).

# BAD; frame-dependent
x += 5

# GOOD; frame-independent
SPEED = 300  # pixels per second
x += SPEED * dt

Rect vs Vector2

Gerber makes an entire video about this because students get confused:

Use pygame.Rect when:

  • You need collision detection (colliderect(), collidepoint())
  • You want to use handy properties like .center, .topleft, .clamp_ip()
  • You're positioning sprites on screen

Use pygame.math.Vector2 when:

  • You need smooth movement with floats (Rects use integers!)
  • You want to normalize directions
  • You need distance calculations
  • You're doing physics with velocity/acceleration

Common pattern; use both:

class Ball(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.pos = pygame.math.Vector2(400, 300)  # float position
        self.vel = pygame.math.Vector2(3, -2)     # float velocity
        self.rect = pygame.Rect(0, 0, 20, 20)     # for collision

    def update(self, dt):
        self.pos += self.vel * dt * 60
        self.rect.center = self.pos  # sync rect to float pos

screen coordinates

Pygame's coordinate system starts at the top-left corner:

  • (0, 0) = top-left
  • x increases going RIGHT
  • y increases going DOWN

So (800, 600) is the bottom-right of an 800x600 window. A bit counterintuitive if you're used to math, but you get used to it fast.

colors

Colors are (R, G, B) tuples with values 0-255:

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED   = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE  = (0, 0, 255)

drawing basics

# Draw a filled rectangle: surface, color, (x, y, width, height)
pygame.draw.rect(screen, RED, (100, 100, 50, 50))

# Draw a circle: surface, color, (center_x, center_y), radius
pygame.draw.circle(screen, BLUE, (400, 300), 30)

# Draw a line: surface, color, start_pos, end_pos, width
pygame.draw.line(screen, WHITE, (0, 0), (800, 600), 2)

The order matters; things drawn later appear on top.

🎨 asset creation tips

Where to find free sprites and tilesets:

  • Kenney.nl: amazing free assets, super polished, great for prototyping
  • itch.io: search "free sprites" or "free tileset", tons of options
  • OpenGameArt.org: community-contributed art, check licenses

Tools for making your own:

  • Aseprite (paid but worth it); pixel art and animation
  • Piskel (free, browser-based); simple pixel art
  • Tiled: tilemap editor, exports JSON your game can load

tips

  • Gerber tip: Keep all constants in a settings.py file; way easier to tune the game later
  • Gerber tip: Always call pygame.quit() at the end; prevents the window from hanging
  • Tip: Use pygame.display.set_caption("Game Title") to set the window title
  • Tip: clock.tick(60) returns milliseconds since last call; divide by 1000 for seconds

common mistakes

  • Forgetting pygame.quit(): the window hangs when you close it
  • Not calling pygame.display.flip(): nothing shows up, you just stare at a black screen wondering why
  • Using pygame.QUIT instead of pygame.quit(): QUIT is an event type, quit() is a function
  • Hardcoding frame rate assumptions: use delta time instead of assuming 60fps
  • Putting draw calls before update: you'll draw the old state, not the new one

# examples [2]

# example 01 · minimal game loop with delta time

The simplest Pygame setup with proper delta time handling

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
🐍
Loading PythonSetting up pandas & numpy...

pygame needs a real window — copy this into a .py file and run it locally.

# example 02 · settings file pattern

Gerber's recommended structure; all constants in one place

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
🐍
Loading PythonSetting up pandas & numpy...

pygame needs a real window — copy this into a .py file and run it locally.

# challenges [2]

# challenge 01/02todo
What are the three main steps in a game loop, in order?
pygame needs a real window. copy this into a .py file and run it locally.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
🐍
Loading PythonSetting up pandas & numpy...
# challenge 02/02todo
Why do you multiply velocity by delta time (dt)? What problem does it solve?
pygame needs a real window. copy this into a .py file and run it locally.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
🐍
Loading PythonSetting up pandas & numpy...