Build Your First Pygame Game on Raspberry Pi: Beginner Walkthrough

//

Simon Gregory

By the end of this guide, you’ll have a real, playable game running on your Raspberry Pi — a moving player square that collects targets, tracks your score, and responds to keyboard input. Pygame is a Python library built for exactly this kind of project, and it runs surprisingly well on Pi hardware. This walkthrough covers everything from installation to a finished game, with every code block explained so you can modify it confidently.

What You’ll Build

  • Project: Pygame collector game on Raspberry Pi
  • Tools Needed: Raspberry Pi 3B+ or newer, Raspberry Pi OS, Python 3, Pygame 2.x
  • Difficulty: Beginner
  • Time Required: 45–60 minutes

What You’ll Need Before You Start

Getting your hardware and software lined up before writing a single line of code saves a lot of frustration. Pygame works best on a Pi connected directly to a display — headless setups (running the Pi without a monitor via SSH) require extra display configuration that’s outside the scope of this walkthrough.

Required Hardware

  • Raspberry Pi 3B+, Pi 4, or Pi 5 (Pi 3B+ is the minimum for smooth Pygame performance at 60fps)
  • MicroSD card with Raspberry Pi OS Bookworm installed (32-bit or 64-bit both work)
  • Monitor connected via HDMI
  • USB keyboard and mouse

Required Software

  • Python 3 — pre-installed on Raspberry Pi OS, confirm with python3 --version
  • pip3 — the Python package manager, also pre-installed
  • A terminal window open on the Pi’s desktop

You can write your code in Thonny IDE, which comes pre-installed on Raspberry Pi OS and offers syntax highlighting and a built-in file runner. Open it from the Programming menu on your desktop.

Installing Pygame on Raspberry Pi

How do you install Pygame on a Raspberry Pi? The process takes about five minutes, but skipping the system update step first causes dependency errors that trip up many first-timers. Run these commands in order from your terminal.

Step-by-Step Installation

  1. Open the terminal on your Raspberry Pi desktop.
  2. Update your system packages: sudo apt update && sudo apt upgrade -y
  3. Install Pygame using pip3: pip3 install pygame
  4. Verify the install worked: python3 -c 'import pygame; print(pygame.ver)'

You should see a version number printed — something like 2.5.2. If the install fails on an older Pi OS version, fall back to a tested stable release: pip3 install pygame==2.1.2. This version handles SDL (Simple DirectMedia Layer, the graphics library Pygame sits on top of) dependencies cleanly on older Raspberry Pi OS builds.

Confirm everything works by running the built-in aliens demo: python3 -m pygame.examples.aliens. A retro shooter should launch. If it does, your Pygame setup is solid.

Understanding the Pygame Game Loop

The game loop is the engine behind every Pygame project. Your Pi runs it dozens of times per second, and each pass does exactly three things: read player input, update the game state, and draw everything to the screen. Miss any one of those phases and your game either freezes, ignores controls, or flickers.

The Three Core Phases

  • Event handling: Check what the player is doing — pressing keys, clicking, or closing the window.
  • Update logic: Move the player, check for collisions, update the score.
  • Draw/render: Clear the screen, draw every object in its new position, push the frame to the display.

The pygame.time.Clock object controls how fast this loop runs. Call clock.tick(60) to cap the loop at 60 frames per second. Without it, the loop runs as fast as your Pi’s CPU allows — which sounds good until your game runs at different speeds on different hardware, and your Pi’s processor hits 100% for no reason.

Here’s the minimal skeleton every Pygame script starts with:

import pygame
import sys

pygame.init()                          # Start all Pygame modules
screen = pygame.display.set_mode((800, 600))  # Create the game window
clock = pygame.time.Clock()            # Create the frame rate controller

running = True
while running:                         # Main game loop starts here
    for event in pygame.event.get():   # Check for events
        if event.type == pygame.QUIT:  # Player closed the window
            running = False

    screen.fill((0, 0, 0))            # Clear screen with black
    pygame.display.flip()             # Push frame to display
    clock.tick(60)                    # Cap at 60fps

pygame.quit()
sys.exit()

This block creates the game window, runs the loop, and exits cleanly. Run it and you’ll see a black 800×600 window. That’s your canvas.

Drawing a Player and Handling Keyboard Input

This is where it gets interesting. You’ll draw a rectangle as your player and move it with the arrow keys. The key method here is pygame.key.get_pressed(), which returns the state of every key on every frame — perfect for smooth, held-down movement.

Player Movement Code

Add these variables before your game loop, then add the movement block inside the loop after event handling:

player_x = 375          # Starting X position
player_y = 275          # Starting Y position
player_speed = 4        # Pixels moved per frame
BLUE = (50, 120, 220)   # Player color as RGB tuple

# Inside the game loop, after event handling:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and player_x > 0:
    player_x -= player_speed
if keys[pygame.K_RIGHT] and player_x < 760:
    player_x += player_speed
if keys[pygame.K_UP] and player_y > 0:
    player_y -= player_speed
if keys[pygame.K_DOWN] and player_y < 560:
    player_y += player_speed

# In the draw section:
pygame.draw.rect(screen, BLUE, (player_x, player_y, 40, 40))

The boundary checks (player_x > 0 and player_x < 760) clamp the player to the screen edges. The 760 limit accounts for the 40-pixel width of the rectangle inside an 800-pixel window. Pygame uses RGB tuples — three numbers from 0 to 255 representing red, green, and blue — for every color you define.

Use pygame.key.get_pressed() for held movement. Use event-based pygame.KEYDOWN inside your event loop for single-press actions like pausing or firing.

Adding a Target and Collision Detection

A moving square alone isn't a game. Add a target the player collects, track the score, and display it on screen. This section introduces pygame.Rect — a rectangle object that handles collision detection with a single method call.

Target and Score Setup

Add these imports and variables at the top of your script:

import random

RED = (220, 60, 60)
score = 0
target_x = random.randint(0, 760)
target_y = random.randint(0, 560)
font = pygame.font.SysFont("monospace", 28)

Collision Detection with pygame.Rect

Inside your game loop, after updating player position, add this collision block:

player_rect = pygame.Rect(player_x, player_y, 40, 40)
target_rect = pygame.Rect(target_x, target_y, 30, 30)

if player_rect.colliderect(target_rect):
    score += 1
    target_x = random.randint(0, 760)
    target_y = random.randint(0, 560)

# In the draw section:
pygame.draw.rect(screen, RED, (target_x, target_y, 30, 30))
score_text = font.render(f"Score: {score}", True, (255, 255, 255))
screen.blit(score_text, (10, 10))

colliderect() returns True when two pygame.Rect objects overlap. On collision, the target jumps to a new random position and your score goes up by one. The screen.blit() call draws the rendered text surface onto the screen at coordinates (10, 10) — top-left corner.

Running Your Game and Fixing Common Issues

Save your script as collector_game.py and run it from the terminal: python3 collector_game.py. A window should open immediately with your player and target visible.

Common Errors and Fixes

pygame.error: No available video device — This appears when you run the script from an SSH session without a display. Pygame needs a screen to draw to. Run your script from the terminal on the Pi's desktop instead, or set the display variable first: export DISPLAY=:0 before running.

ModuleNotFoundError: No module named 'pygame' — pip installed Pygame for a different Python version. Try python3 -m pip install pygame to make sure you're installing to the right interpreter.

Slow or choppy performance on Pi Zero or Pi 2 — Reduce the window size to 480x320 and lower your clock tick to 30fps. These older models handle smaller render areas much better. The Pi 3B+ and Pi 4 run 800x600 at 60fps without issues.

Where to Take Your Pygame Project Next

You've built a working game. The structure you understand now — init, game loop, event handling, draw, clock — applies to every Pygame project you'll ever build. So what comes next?

  • Add a countdown timer: Use pygame.time.get_ticks() to track elapsed time and introduce a "game over" state when the timer hits zero. This teaches you game state management.
  • Replace rectangles with sprites: Load a PNG image with pygame.image.load('player.png') and draw it instead of a plain rectangle. Suddenly your game looks like a real game.
  • Add sound effects: pygame.mixer.Sound('collect.wav').play() fires a sound on collision. Pygame's mixer module handles audio with just a few lines.
  • Build a two-player version: Map WASD keys to a second player rectangle. Two players, one keyboard, one screen — a natural fit for Pi game nights.

Ready to go further? Check out our related guide on beginner Python projects for Raspberry Pi, or explore building a retro game console with RetroPie to run your Pygame creations on a dedicated arcade setup. Every project you finish is the starting point for the next one.

Frequently Asked Questions

Can Pygame actually run on a Raspberry Pi without lag?

Yes — on a Raspberry Pi 3B+ or newer, Pygame runs smoothly at 60fps for 2D games at standard resolutions like 800x600. The Pi Zero and Pi 2 can handle Pygame at lower resolutions and 30fps. Stick to 2D rendering and avoid loading large uncompressed images for best performance.

What version of Pygame works with Raspberry Pi OS Bookworm?

Pygame 2.x installs cleanly on Raspberry Pi OS Bookworm using pip3 install pygame. If you're on an older OS version and hit dependency errors, install pygame==2.1.2 as a stable fallback.

Why is Pygame running slowly on my Raspberry Pi?

The most common cause is a missing clock.tick() call, which lets the game loop run uncapped and pins your CPU. Add clock.tick(60) at the end of your loop. Also reduce your window size if you're on a Pi Zero or Pi 2.

How do I stop my Pygame game from freezing?

A frozen game almost always means your event loop isn't processing events. Make sure pygame.event.get() runs on every iteration of your main loop. Skipping this call causes the OS to think your window has stopped responding.

What games can I make with Pygame on Raspberry Pi?

Pygame handles any 2D game well — platformers, top-down shooters, puzzle games, and collectors like the one in this guide. It's also a solid base for educational simulations and interactive art projects. The library's built-in support for sprites, sound, and fonts covers most beginner and intermediate game types.

Spread the love