Pygame para principiantes permite aprender programación creando ventanas, movimiento, colisiones, puntuación, imágenes y sonido. La biblioteca está orientada a juegos y aplicaciones multimedia 2D, pero también es útil para simulaciones, prototipos y proyectos educativos.
En esta guía construirás un pequeño juego donde un personaje se mueve por la pantalla y recoge objetivos. El proyecto enseña el bucle principal, los eventos, el tiempo entre fotogramas y la separación entre actualización y dibujo.
Instalar Pygame
Crea un entorno virtual antes de instalar la biblioteca:
python -m venv .venv
# PowerShell en Windows
.venv\Scripts\Activate.ps1
# Command Prompt en Windows
.venv\Scripts\activate.bat
# macOS o Linux
source .venv/bin/activate
python -m pip install pygameLa guía de entornos virtuales con venv explica cómo aislar dependencias y seleccionar el intérprete correcto.
Comprueba la instalación:
import pygame
print(pygame.version.ver)La documentación oficial de Pygame reúne referencias sobre eventos, superficies, sprites, audio, fuentes y dibujo.
Crear una ventana
import pygame
pygame.init()
WIDTH = 800
HEIGHT = 500
FPS = 60
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Mi primer juego")
clock = pygame.time.Clock()pygame.init() inicializa los módulos principales. set_mode() crea la superficie visible y Clock controla el ritmo del juego.
El bucle principal
Todo juego repite tres fases: leer eventos, actualizar el estado y dibujar.
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((25, 25, 35))
pygame.display.flip()
clock.tick(FPS)
pygame.quit()Procesar pygame.QUIT permite cerrar la ventana. display.flip() presenta el fotograma dibujado y tick() limita la velocidad.
Crear al jugador
player = pygame.Rect(100, 220, 40, 40)
player_speed = 250Un Rect guarda posición y tamaño. Puede utilizarse para dibujar y detectar colisiones.
pygame.draw.rect(
screen,
(70, 180, 255),
player,
)Movimiento independiente de los FPS
La velocidad debe relacionarse con el tiempo transcurrido:
dt = clock.tick(FPS) / 1000
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= player_speed * dt
if keys[pygame.K_RIGHT]:
player.x += player_speed * dt
if keys[pygame.K_UP]:
player.y -= player_speed * dt
if keys[pygame.K_DOWN]:
player.y += player_speed * dtdt representa segundos desde el fotograma anterior. Multiplicarlo por la velocidad evita que el personaje se mueva más rápido en equipos que producen más fotogramas.
La guía de lógica de programación con Python explica condiciones, estados y bucles.
Mantener al jugador dentro de la pantalla
player.clamp_ip(screen.get_rect())clamp_ip() ajusta la posición para mantener el rectángulo dentro de la pantalla.
Crear un objetivo aleatorio
import random
TARGET_SIZE = 24
target = pygame.Rect(
random.randint(0, WIDTH - TARGET_SIZE),
random.randint(0, HEIGHT - TARGET_SIZE),
TARGET_SIZE,
TARGET_SIZE,
)La guía del módulo random en Python explica números, elecciones y mezclas.
Detectar una colisión
if player.colliderect(target):
score += 1
target.x = random.randint(0, WIDTH - target.width)
target.y = random.randint(0, HEIGHT - target.height)colliderect() devuelve verdadero cuando dos rectángulos se superponen. Las cajas rectangulares son suficientes para muchos juegos 2D sencillos.
Mostrar la puntuación
font = pygame.font.Font(None, 36)
score_surface = font.render(
f"Puntuación: {score}",
True,
(240, 240, 240),
)
screen.blit(score_surface, (20, 20))La fuente crea una superficie de texto y blit() la coloca en la pantalla.
Código completo del primer juego
import random
import pygame
pygame.init()
WIDTH = 800
HEIGHT = 500
FPS = 60
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Recoge el objetivo")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 36)
player = pygame.Rect(100, 220, 40, 40)
player_speed = 250
target = pygame.Rect(
random.randint(0, WIDTH - 24),
random.randint(0, HEIGHT - 24),
24,
24,
)
score = 0
running = True
while running:
dt = clock.tick(FPS) / 1000
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= player_speed * dt
if keys[pygame.K_RIGHT]:
player.x += player_speed * dt
if keys[pygame.K_UP]:
player.y -= player_speed * dt
if keys[pygame.K_DOWN]:
player.y += player_speed * dt
player.clamp_ip(screen.get_rect())
if player.colliderect(target):
score += 1
target.x = random.randint(0, WIDTH - target.width)
target.y = random.randint(0, HEIGHT - target.height)
screen.fill((25, 25, 35))
pygame.draw.rect(screen, (70, 180, 255), player)
pygame.draw.rect(screen, (255, 180, 60), target)
score_surface = font.render(
f"Puntuación: {score}",
True,
(240, 240, 240),
)
screen.blit(score_surface, (20, 20))
pygame.display.flip()
pygame.quit()Separar responsabilidades
Cuando el proyecto crece, divide el código en funciones:
def handle_events():
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
return True
def update_player(player, speed, dt):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= speed * dt
if keys[pygame.K_RIGHT]:
player.x += speed * dt
def draw_scene(screen, player, target):
screen.fill((25, 25, 35))
pygame.draw.rect(screen, (70, 180, 255), player)
pygame.draw.rect(screen, (255, 180, 60), target)La guía de funciones en Python explica parámetros, retornos y separación de responsabilidades.
Utilizar imágenes
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent
player_path = BASE_DIR / "assets" / "player.png"
player_image = pygame.image.load(
player_path
).convert_alpha()
screen.blit(player_image, player)convert_alpha() optimiza la imagen conservando transparencia. La guía de pathlib en Python ayuda a construir rutas portables.
Sonido y música
collect_sound = pygame.mixer.Sound(
BASE_DIR / "assets" / "collect.wav"
)
if player.colliderect(target):
collect_sound.play()Carga los archivos una sola vez durante la inicialización, no dentro del bucle principal.
Sprites y grupos
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((40, 40))
self.image.fill((70, 180, 255))
self.rect = self.image.get_rect(center=(100, 250))La guía de programación orientada a objetos explica cómo organizar jugadores, enemigos y escenas.
Estados del juego
Una aplicación completa puede tener estados como menú, jugando, pausa y fin:
state = "menu"
if state == "menu":
draw_menu()
elif state == "playing":
update_game()
elif state == "game_over":
draw_game_over()Prácticas recomendadas
- Procesa eventos en cada fotograma.
- Usa delta time para movimiento continuo.
- Carga imágenes, fuentes y sonidos una sola vez.
- Separa actualización, dibujo y eventos.
- Construye rutas desde la carpeta del script.
- Mantén un límite de FPS.
- Prueba colisiones y límites por separado.
Errores frecuentes
- Olvidar llamar a
pygame.quit(). - No procesar
pygame.QUIT. - Mover objetos sin utilizar el tiempo transcurrido.
- Cargar recursos dentro del bucle.
- Dibujar antes de limpiar la pantalla.
- Actualizar la pantalla varias veces por fotograma.
- Guardar todo el proyecto en una sola función enorme.
Más recursos oficiales
El índice oficial de tutoriales de Pygame reúne ejemplos de sprites, eventos, sonido y gráficos.
Conclusión
Pygame transforma fundamentos de Python en resultados visuales. Domina primero la ventana, el bucle principal, los eventos, el movimiento con delta time y las colisiones. Después añade texto, imágenes, sonido, clases y estados. Un juego pequeño terminado ofrece una base mejor que varios proyectos grandes incompletos.






