Showcase
Crear videojuegos
Aprende a hacer juegos 2D en Python con Pyzed, desde tu primer bucle de juego hasta plataformas, shooters y puzles completos: una ruta paso a paso con ejemplos animados, consejos y tres juegos terminados.
Pyzed es una librería de interfaces, pero ya trae todo lo que necesita un juego 2D: un
pz.canvas dibujado por la GPU, un bucle que se ejecuta una vez por fotograma, las teclas
que están pulsadas ahora mismo y toda la biblioteca de widgets para construir menús y HUD
encima de la acción. Cada juego de estas páginas es un programa completo y jugable en
examples/games/, comprobado por
las pruebas en cada cambio.








Aprende a crear juegos
Sección titulada «Aprende a crear juegos»Una ruta desde cero hasta juegos completos. Cada paso es un tutorial con un objetivo, el tiempo que lleva, lo que necesitas saber antes, el código completo e ideas para seguir. Si nunca has escrito un juego, empieza por el 1; si ya lo has hecho, salta a lo que necesites.
flowchart LR
A["1 · Bucle y teclas"] --> B["2 · Sprites y animación"] --> C["3 · Colisiones y física"]
C --> D["4 · Plataformas"]
C --> E["5 · Asteroids"]
B --> F["6 · Puzle: 2048"]
D --> G["7 · Menús, HUD, ajustes"]
E --> G
F --> G
G --> H["8 · Guardado y sonido"]
Juegos completos
Sección titulada «Juegos completos»Tres juegos más grandes para leer, jugar y desmontar. Crecen en dificultad:
Ejecuta cualquier juego desde la carpeta del repositorio; cambia el nombre del archivo para los demás:
uv run --with pyzed-ui python examples/games/neon_invaders.pypython3 -m venv .venvsource .venv/bin/activatepython -m pip install pyzed-uipython examples/games/neon_invaders.pypy -m venv .venv.venv\Scripts\Activate.ps1python -m pip install pyzed-uipython examples\games\neon_invaders.pypython3 examples/games/neon_invaders.pypy examples\games\neon_invaders.pyLas piezas
Sección titulada «Las piezas»| Qué | API | Para qué |
|---|---|---|
| Bucle por fotograma | pz.frames(callback) en subscriptions() |
callback(dt) una vez por fotograma (sincronizado con la pantalla); dt son los segundos desde el anterior. |
| Temporizador fijo | pz.every(segundos, callback) |
Juegos por turnos o en cuadrícula que avanzan a ritmo fijo (Snake). |
| Pulsaciones | on_key(combo) |
Acciones puntuales: saltar, pausar, reiniciar ("space", "enter", "ctrl-r"). |
| Soltar teclas | on_key_up(key) |
Mecánicas de cargar y soltar, parar un sonido. |
| Teclas mantenidas | pz.pressed(), pz.is_pressed("left", "a") |
Movimiento continuo y disparo automático, consultados en cada fotograma. |
| Movimiento | game.axis(neg, pos), game.vector() |
-1/0/1 a partir de dos grupos de teclas; una dirección normalizada con flechas/WASD. |
| Dibujo | pz.canvas([...]) con pyzed.draw |
Rectángulos, círculos, trazados, texto, transformaciones. |
| Sprites | draw.image(src, x, y, w, h) y game.sprite(filas, paleta) |
Imágenes (se decodifican una vez y quedan en caché) o pixel art escrito como texto. |
| Colisiones | game.Rect, game.circle_rect |
Solapamiento de cajas; por dónde golpea una pelota a una caja, para rebotar. |
| Efectos | game.glow, game.Particles, game.Shake |
Luces neón, explosiones y chispas, temblor de pantalla. |
| HUD y menús | pz.stack([canvas, widgets]) |
Puntuaciones, barras de vida y pantallas de pausa con glass, bloom y animaciones. |
El bucle
Sección titulada «El bucle»Un juego es un pz.App normal. Devuelve pz.frames(self.tick) desde subscriptions() y
el runtime llama a tick(dt) antes de cada fotograma. Mueve las cosas velocidad × dt
para que vayan igual de rápido a 60, 120 o 144 Hz:
import pyzed as pzfrom pyzed import draw, game
class Ship(pz.App): size = (480, 320)
def __init__(self): self.x, self.y = 240, 160
def subscriptions(self): return [pz.frames(self.tick)]
def tick(self, dt): dx, dy = game.vector() # flechas / WASD, diagonales normalizadas self.x += dx * 300 * dt self.y += dy * 300 * dt
def view(self): return pz.canvas([draw.background("#0b0e14"), *game.glow(self.x, self.y, 14, "#22d3ee")], width=480, height=320)
pz.run(Ship)dt se limita a un cuarto de segundo, así que arrastrar la ventana o parar en un
breakpoint nunca hace que el juego salte hacia delante. Donde la pantalla no espera a la
sincronización vertical (renderizado por software), max_fps (240 por defecto) evita que
el bucle consuma toda la CPU.
Entrada
Sección titulada «Entrada»on_key es para acciones que ocurren una vez por pulsación; pz.pressed() para lo que
ocurre mientras una tecla está pulsada. Ambos ven todas las teclas, tenga el foco el
widget que lo tenga.
def on_key(self, combo): # "space", "p", "shift-r"... if combo == "p": self.paused = not self.paused
def tick(self, dt): if pz.is_pressed("space") and self.cooldown <= 0: self.fire() # disparo automático mientras Space está pulsadaEl ratón llega desde el propio canvas: on_move(x, y), on_press(x, y), on_release(),
on_right_press(x, y) y on_scroll(dx, dy), en coordenadas del canvas.
Sprites
Sección titulada «Sprites»draw.image dibuja un PNG/JPEG (o bytes RGBA) dentro de una caja, opcionalmente girado y
con transparencia. Se decodifica una vez por origen y queda en caché, así que dibujar el
mismo sprite cientos de veces por fotograma es barato. Usa pixelated=True para pixel art
ampliado.
draw.image("assets/ship.png", self.x - 16, self.y - 16, 32, 32, rotation=self.angle)Para juegos retro ni siquiera hacen falta archivos: game.sprite convierte texto en pixel
art, con una forma por color sea cual sea el tamaño del sprite.
INVADER = ["..#.....#..", "...#...#...", "..#######..", ".##.###.##.", "###########"]game.sprite(INVADER, {"#": "#a3e635"}, x, y, scale=4)El HUD y los menús son widgets
Sección titulada «El HUD y los menús son widgets»Apila widgets sobre el canvas con pz.stack. Puntuaciones, barras de vida, insignias y
menús de pausa son componentes normales de Pyzed, así que tienen temas, paneles glass,
bloom y animaciones de entrada sin esfuerzo: la parte difícil de la interfaz de un juego
ya está hecha.
hud = pz.container(pz.row([score, pz.hspace(), ui.badge(f"Wave {self.wave}")]), padding=(8, 14)).style(glass=True, radius=12)return pz.stack([self.scene(), hud], width=W, height=H)Consejos de rendimiento
Sección titulada «Consejos de rendimiento»Más en Consejos para crear juegos.
- Haz poco trabajo Python por fotograma: listas y números simples, sin crear estructuras grandes cada vez.
- Agrupa formas:
draw.rectsdibuja muchos rectángulos de un color como una sola forma (es lo que usagame.sprite). - Limita las partículas (
game.Particles(limit=...)) y elimina las balas que salen de la pantalla. - Solo el canvas cambia en cada fotograma; los widgets del HUD son baratos de reconstruir,
pero
pz.memopuede cachear los costosos. - Prueba la lógica sin ventana: llama a
tick(1 / 60)en un bucle y comprueba el estado, como hacetests/test_game.py.App.screenshotrenderiza cualquier momento del juego a un PNG.