Bucle de juego
Pyxen ejecuta tu juego a una tasa fija de 30 fotogramas por segundo. No escribes un bucle principal — defines dos funciones y Pyxen las llama por ti.
start() y update()
def start():
# se llama una vez, al principio
pass
def update():
# se llama cada fotograma, 30 veces por segundo
pass
start() es donde configuras tu mundo: generar entidades, colocarlas, configurar la escena.
update() es donde se ejecuta tu lógica de juego: leer entrada, mover entidades, comprobar condiciones, actualizar estado. Después de cada llamada a update(), el motor renderiza el fotograma.
Tasa de fotogramas fija
Cada fotograma toma exactamente la misma cantidad de tiempo: 1/30 de segundo (~33ms). Esto significa:
- La lógica del juego es determinista — las mismas entradas producen los mismos resultados
- Puedes contar fotogramas directamente (
time.frame) en vez de trabajar con deltas de tiempo variables - El control temporal y el inspector de fotogramas funcionan de forma fiable porque cada fotograma es una instantánea limpia
Puedes usar time.dt (delta time) si prefieres movimiento basado en tiempo, pero siempre será 1/30.
Orden de fotograma
Cada fotograma, Pyxen ejecuta estos pasos en orden:
- Entrada — lee el estado de teclado, ratón, táctil y mando
- update() — tu código se ejecuta
- Colisión — el motor resuelve cuerpos de cuadrícula y llama callbacks de colisión
- Renderizado — el motor dibuja todas las entidades visibles
Esto significa que cuando lees la entrada en update(), los valores son frescos. Cuando mueves una entidad, la resolución de colisión ocurre justo después.
Callbacks de colisión
Si defines on_collision o on_tile_collision en el nivel superior, el motor las llama durante el paso de colisión:
def on_collision(entity, other):
# dos cuerpos de cuadrícula se superpusieron
pass
def on_tile_collision(entity, tile):
# un cuerpo de cuadrícula golpeó un tile del tilemap
pass
Estas se ejecutan después de update() pero antes del renderizado.
Temporización
El módulo pyxen.time te da:
| Propiedad | Valor | Uso |
|---|---|---|
time.frame | 0, 1, 2, ... | Contador de fotogramas desde el inicio |
time.dt | 0.0333... | Delta time (siempre 1/30) |
time.t | 0.0, 0.033, 0.066, ... | Tiempo transcurrido en segundos |
time.fps | 30 | Fotogramas por segundo |
Para eventos temporizados, puedes usar cualquier enfoque:
# Basado en fotogramas: disparar cada 60 fotogramas (2 segundos)
if time.frame % 60 == 0:
fire()
# Basado en tiempo: lo mismo
if int(time.t * 30) % 60 == 0:
fire()
Contar fotogramas es generalmente más simple y predecible.