Pygame for Beginners: Build Your First Game

Published on: July 10, 2026
Reading time: 6 minutes
Criação de jogos para iniciantes usando Pygame em Python

Creating a small game is a practical way to learn how a program reacts continuously to input. With Pygame for beginners, you can open a graphical window, draw shapes, process keyboard events, control frame rate, detect collisions, display a score, and build a complete playable project with ordinary Python code.

This guide starts with installation and the basic game loop, then builds a simple dodge game. The player moves horizontally while blocks fall from the top of the screen. Every block that reaches the bottom increases the score; touching one ends the round.

Pygame is especially useful after you understand basic variables, loops, functions, and conditions. A smaller project using only the standard library is available in the companion tutorial to build a Snake game with Turtle.

What Is Pygame?

Pygame is a collection of Python modules for creating games and multimedia applications. It provides access to windows, drawing, images, fonts, sound, input events, timing, and collision-friendly rectangle objects.

The official Pygame documentation contains the API reference, while the Pygame introduction explains the basic structure of a program.

Pygame is not a visual game engine. You write the loop and game rules yourself, which makes it a strong learning tool. For larger projects, classes and Python dataclasses can help organize players, enemies, and configuration.

Install Pygame

Create and activate a virtual environment, then install the package:

python -m pip install pygame

Verify the installation:

python -m pygame.examples.aliens

If a Pygame example opens, the package and graphical environment are working. In an editor, ensure the selected Python interpreter is the one where you installed Pygame.

Understand the Game Loop

A real-time game repeatedly performs four steps:

  1. Read events and input.
  2. Update positions and game state.
  3. Draw the current frame.
  4. Wait long enough to maintain a controlled frame rate.

The loop continues until the player closes the window or a game condition stops it. A clock prevents the game from running at a different speed on every computer.

Create Your First Pygame Window

import pygame

pygame.init()

WIDTH = 800
HEIGHT = 600
BACKGROUND = (20, 24, 35)

screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My First Pygame")

clock = pygame.time.Clock()
running = True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill(BACKGROUND)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

pygame.init() initializes imported Pygame modules. set_mode() creates the display surface. pygame.display.flip() presents the completed frame, and clock.tick(60) limits the loop to approximately 60 frames per second.

Coordinates, Colors, and Rectangles

Pygame uses a coordinate system whose origin is the top-left corner. The x-coordinate increases to the right and the y-coordinate increases downward.

Colors are usually RGB tuples:

WHITE = (255, 255, 255)
RED = (239, 68, 68)
BLUE = (59, 130, 246)

A pygame.Rect stores position and size and includes convenient properties such as left, right, centerx, and bottom.

player = pygame.Rect(375, 520, 50, 50)
pygame.draw.rect(screen, BLUE, player)

Rectangles also simplify collision detection. The method player.colliderect(enemy) returns whether two rectangles overlap.

Process Continuous Keyboard Input

Window events are read from pygame.event.get(). For movement that continues while a key is held, use pygame.key.get_pressed().

keys = pygame.key.get_pressed()

if keys[pygame.K_LEFT]:
    player.x -= player_speed

if keys[pygame.K_RIGHT]:
    player.x += player_speed

Keep the player inside the window with clamp_ip():

player.clamp_ip(screen.get_rect())

This is clearer than writing four separate boundary comparisons. Game code often benefits from small functions with clear return values rather than one very long loop.

Make Movement Independent of Frame Rate

Moving a fixed number of pixels per frame can still behave differently if the frame rate drops. Use elapsed time, commonly called delta time:

delta_time = clock.tick(60) / 1000
player.x += int(player_speed * delta_time)

If player_speed represents pixels per second, multiplying by seconds elapsed keeps movement more consistent. For this beginner project, enemy spawning also uses elapsed time rather than a random chance on every frame.

Create Falling Enemies

Store enemy rectangles in a list. A timer controls when a new one appears:

import random

enemies = []
spawn_timer = 0
spawn_interval = 700

spawn_timer += delta_time * 1000

if spawn_timer >= spawn_interval:
    enemy_width = 45
    x = random.randint(0, WIDTH - enemy_width)
    enemies.append(pygame.Rect(x, -45, 45, 45))
    spawn_timer = 0

For security-sensitive random values, Python has the secrets module, but ordinary game randomness should use random because cryptographic unpredictability is unnecessary here.

Move and Remove Enemies Safely

Do not remove items from a list while iterating over that same list unless you carefully control the iteration. A list comprehension can keep only active enemies:

for enemy in enemies:
    enemy.y += int(enemy_speed * delta_time)

active_enemies = []

for enemy in enemies:
    if enemy.top <= HEIGHT:
        active_enemies.append(enemy)
    else:
        score += 1

enemies = active_enemies

This approach also provides a natural place to increase the score when an obstacle leaves the screen.

Detect Collisions

if any(player.colliderect(enemy) for enemy in enemies):
    game_over = True

any() stops after finding the first collision. For image-based games, rectangular collisions are often good enough. Pygame also supports masks for pixel-level collision tests when accurate sprite shapes are required.

Render Text and Score

font = pygame.font.Font(None, 36)

score_surface = font.render(
    f"Score: {score}",
    True,
    WHITE,
)
screen.blit(score_surface, (20, 20))

Rendering creates a surface containing the text. blit() copies that surface to the main display at the chosen position.

Complete Beginner Dodge Game

import random
import pygame

pygame.init()

WIDTH = 800
HEIGHT = 600
FPS = 60

BACKGROUND = (17, 24, 39)
PLAYER_COLOR = (59, 130, 246)
ENEMY_COLOR = (239, 68, 68)
TEXT_COLOR = (255, 255, 255)

screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Python Dodge Game")

clock = pygame.time.Clock()
font = pygame.font.Font(None, 36)
large_font = pygame.font.Font(None, 64)

player = pygame.Rect(
    WIDTH // 2 - 25,
    HEIGHT - 80,
    50,
    50,
)

player_speed = 360
enemy_speed = 240
spawn_interval = 700
spawn_timer = 0

enemies = []
score = 0
running = True
game_over = False

while running:
    delta_time = clock.tick(FPS) / 1000

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if (
            event.type == pygame.KEYDOWN
            and event.key == pygame.K_r
            and game_over
        ):
            enemies.clear()
            player.centerx = WIDTH // 2
            score = 0
            spawn_timer = 0
            game_over = False

    if not game_over:
        keys = pygame.key.get_pressed()

        if keys[pygame.K_LEFT] or keys[pygame.K_a]:
            player.x -= int(player_speed * delta_time)

        if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
            player.x += int(player_speed * delta_time)

        player.clamp_ip(screen.get_rect())

        spawn_timer += delta_time * 1000

        if spawn_timer >= spawn_interval:
            size = random.randint(35, 65)
            x = random.randint(0, WIDTH - size)
            enemies.append(pygame.Rect(x, -size, size, size))
            spawn_timer = 0

        for enemy in enemies:
            enemy.y += int(enemy_speed * delta_time)

        active_enemies = []

        for enemy in enemies:
            if enemy.top <= HEIGHT:
                active_enemies.append(enemy)
            else:
                score += 1

        enemies = active_enemies

        if any(player.colliderect(enemy) for enemy in enemies):
            game_over = True

    screen.fill(BACKGROUND)
    pygame.draw.rect(screen, PLAYER_COLOR, player)

    for enemy in enemies:
        pygame.draw.rect(screen, ENEMY_COLOR, enemy)

    score_surface = font.render(
        f"Score: {score}",
        True,
        TEXT_COLOR,
    )
    screen.blit(score_surface, (20, 20))

    if game_over:
        message = large_font.render(
            "Game Over",
            True,
            TEXT_COLOR,
        )
        restart = font.render(
            "Press R to restart",
            True,
            TEXT_COLOR,
        )

        screen.blit(
            message,
            message.get_rect(center=(WIDTH // 2, HEIGHT // 2 - 25)),
        )
        screen.blit(
            restart,
            restart.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 30)),
        )

    pygame.display.flip()

pygame.quit()

Save the file as dodge_game.py, then run python dodge_game.py. Move with the left and right arrows or A and D. After a collision, press R to restart.

How the Complete Program Is Organized

  • Initialization: starts Pygame, creates the window, fonts, and clock.
  • State: stores the player, enemies, score, timers, and game-over flag.
  • Events: handles closing the window and restarting.
  • Update: moves objects, spawns enemies, removes old ones, and detects collisions.
  • Render: clears the screen and draws the latest state.
  • Timing: limits FPS and calculates delta time.

As the project grows, extract those responsibilities into functions or classes. Add Python logging for startup errors, missing assets, and unexpected failures instead of filling the loop with print calls.

Add Images and Sound

Replace a colored rectangle with an image:

player_image = pygame.image.load("player.png").convert_alpha()
player_image = pygame.transform.scale(
    player_image,
    player.size,
)

screen.blit(player_image, player)

Load assets once before the game loop. Repeated disk access and conversion inside every frame will reduce performance.

For sound:

pygame.mixer.music.load("music.ogg")
pygame.mixer.music.play(-1)

hit_sound = pygame.mixer.Sound("hit.wav")

Use files you have permission to distribute. Keep asset paths relative to a known project directory; the Python pathlib guide shows a reliable way to build those paths.

Common Beginner Mistakes

  • Forgetting to process the event queue, causing the window to appear frozen.
  • Not limiting FPS, making movement hardware-dependent.
  • Loading images or fonts inside the game loop.
  • Updating the display before drawing the full frame.
  • Removing list items during a forward iteration.
  • Mixing event handling, updating, and drawing into one unstructured block.
  • Using fixed per-frame movement without considering delta time.
  • Calling pygame.quit() before the loop has ended.

Ways to Extend the Project

  • Increase enemy speed as the score rises.
  • Add lives instead of ending after one collision.
  • Save the high score to JSON.
  • Add sprites and animation frames.
  • Add a start screen and pause state.
  • Create separate Player and Enemy classes.
  • Add sound effects and background music.
  • Write unit tests for non-graphical helper functions.

For another playable project, continue with the Snake game in Python. It demonstrates grid movement and a growing body rather than continuous pixel movement.

Frequently Asked Questions

Is Pygame included with Python?

No. Install it with python -m pip install pygame.

Can Pygame create professional games?

It can create complete 2D games and prototypes. Larger teams may prefer engines with built-in editors, asset pipelines, and deployment tools.

Why does my window stop responding?

The program must regularly process pygame.event.get(). Long blocking tasks inside the loop prevent events and drawing from being handled.

Does Pygame support controllers?

Yes. Its joystick and controller APIs can read supported gamepads.

Can I export a Pygame game as an executable?

Packaging tools such as PyInstaller can bundle the program, but you must include images, sounds, fonts, and other asset files correctly.

Conclusion

Pygame teaches the core architecture behind real-time applications: input, state updates, rendering, timing, and collision detection. The dodge game provides a complete foundation without hiding the logic behind a visual editor.

Start by changing colors, speeds, sizes, and spawn intervals. Then add one feature at a time and reorganize the code when repetition appears. That process develops both game-design intuition and stronger Python programming habits.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Jogo da forca para iniciantes desenvolvido com Python
    Projects
    Foto de perfil de Leandro Hirt da Academify

    Build a Hangman Game in Python

    Build a complete Hangman game in Python with random words, input validation, repeated-letter checks, lives, ASCII art, and replay support.

    Ler mais

    Tempo de leitura: 5 minutos
    10/07/2026
    Quiz interativo no terminal desenvolvido com Python
    Projects
    Foto de perfil de Leandro Hirt da Academify

    Build a Terminal Quiz Game in Python

    Build a terminal quiz game in Python with questions, input validation, scoring, shuffled answers, replay support, JSON loading, and tests.

    Ler mais

    Tempo de leitura: 4 minutos
    10/07/2026
    Jogo de adivinhação de números desenvolvido com Python
    Projects
    Foto de perfil de Leandro Hirt da Academify

    Build a Number Guessing Game in Python

    Build a number guessing game in Python with random numbers, input validation, hints, limited attempts, replay support, and clean functions.

    Ler mais

    Tempo de leitura: 5 minutos
    10/07/2026
    Desenhos para iniciantes usando Turtle em Python
    Projects
    Foto de perfil de Leandro Hirt da Academify

    Python Turtle Drawing: Complete Beginner Guide

    Learn Python Turtle drawing from scratch: move the turtle, draw shapes, use colors, handle keys, and create a complete geometric

    Ler mais

    Tempo de leitura: 5 minutos
    10/07/2026
    Ilustração de uma cobra com o logo do Python centralizado
    Projects
    Foto de perfil de Leandro Hirt da Academify

    Build a Snake Game in Python with Turtle

    Build a complete Snake game in Python with Turtle. Add movement, food, collisions, body growth, scoring, and keyboard controls.

    Ler mais

    Tempo de leitura: 6 minutos
    10/07/2026
    Projeto clássico do jogo Pong desenvolvido com Python
    Projects
    Foto de perfil de Leandro Hirt da Academify

    Build Your First Pong Game with Python

    Build your first Pong game with Python and the Turtle module: window setup, paddles, ball physics, collision detection, scoreboard, and

    Ler mais

    Tempo de leitura: 7 minutos
    03/06/2026