Sprites y renderizado
Pyxen renderiza tu juego usando un renderizador 2D respaldado por Metal. Todo lo visible en pantalla es una entidad con un componente Sprite.
Sprites
Un sprite le dice al motor qué dibujar para una entidad. Creas uno referenciando una imagen de tu proyecto:
player = world.spawn(sprite=Sprite("hero"))
La cadena "hero" hace referencia a una imagen llamada hero en los assets de tu proyecto.
Hojas de tiles
La mayoría de juegos usan hojas de tiles — una única imagen que contiene muchos fotogramas o tiles organizados en una cuadrícula. Seleccionas una región de la imagen con el parámetro tile:
Sprite("characters", tile=(0, 0, 16, 16)) # primer tile
Sprite("characters", tile=(16, 0, 16, 16)) # segundo tile
Sprite("characters", tile=(0, 16, 16, 16)) # tile en la segunda fila
Los cuatro valores son (x, y, ancho, alto) en píxeles, medidos desde la esquina superior izquierda de la imagen.
Animaciones de sprites
Si creas animaciones con nombre en el editor de sprites, puedes reproducirlas directamente:
player = world.spawn(
sprite=Sprite("hero", animation="walk"),
x=100, y=50
)
El motor lee la secuencia de fotogramas y los FPS de los metadatos del sprite y avanza los fotogramas automáticamente. Para cambiar de animación, asigna un nuevo sprite:
player.sprite = Sprite("hero", animation="jump")
Para animaciones de una sola vez (como un ataque o muerte), establece loop=False y comprueba cuándo termina:
player.sprite = Sprite("hero", animation="attack", loop=False)
def update():
if player.animation and player.animation.finished:
player.sprite = Sprite("hero", animation="idle")
El componente e.animation te da acceso de solo lectura al estado actual: .name, .frame, .playing, .finished. Consulta la referencia de Entity para más detalles.
También puedes animar manualmente cambiando el tile en cada frame:
def update():
frame = time.frame % 4
player.sprite = Sprite("hero", tile=(frame * 16, 0, 16, 16))
Punto de pivote
Por defecto, un sprite se dibuja desde su esquina superior izquierda. Puedes cambiar el punto de pivote para controlar dónde se ancla el sprite:
Sprite("hero", tile=(0, 0, 16, 16), pivot=(8, 8))
Esto centra el sprite en la posición de la entidad. El pivote está en coordenadas de píxeles relativas al tile. Establecer el pivote en el centro del tile es la opción más común — hace que la rotación y el escalado se comporten de forma intuitiva.
Tintado de color
Puedes tintar el sprite de cualquier entidad configurando su color:
player.color = (1.0, 0.5, 0.5, 1.0) # tinte rojizo
El color es una tupla RGBA con valores de 0.0 a 1.0. Blanco (1, 1, 1, 1) significa sin tintado. Puedes usar el canal alfa para transparencia:
ghost.color = (1, 1, 1, 0.5) # 50% transparente
También puedes animar el color y el alfa suavemente con tweens:
ghost.tween("alpha", to=0, duration=0.5, ease="out_quad") # desvanecer
Para efectos continuos como pulsación o parpadeo, usa animaciones:
ghost.animate("alpha", by=0.3, center=0.7, speed=4.0) # parpadeo
Cámara
La cámara controla qué parte del mundo es visible. Crea una generando una entidad con un componente Camera:
cam = world.spawn(camera=Camera(), x=160, y=90)
Mueve la cámara para seguir al jugador:
def update():
cam.x = player.x
cam.y = player.y
La cámara soporta zoom:
cam.camera.zoom = 2.0 # acercar 2x
Puedes animar el zoom suavemente con un tween:
cam.tween("zoom", to=2.0, duration=0.5, ease="out_quad")
Resolución
Los juegos de Pyxen se ejecutan a una resolución predeterminada de 320x180 píxeles. Esta es una elección deliberada — la baja resolución hace que el pixel art se vea nítido y mantiene el renderizado rápido. El motor escala la salida para llenar la pantalla.
Texto
El componente Text renderiza texto de mapa de bits. Crea una entidad de texto así:
label = world.spawn(text=Text("Hello, world!"))
Por defecto, el texto usa la fuente de píxeles integrada. Para usar una fuente personalizada creada con el Editor de fuentes:
title = world.spawn(text=Text("Game Over", font="myfont"))
Actualiza el texto en tiempo de ejecución modificando la propiedad text:
def update():
score_label.text = Text(f"Score: {score}")
Consulta la referencia de Text para la API completa.
Orden de dibujo
Las entidades se dibujan en este orden:
- Capa — las capas inferiores se dibujan primero (capa 0 detrás de capa 1)
- Profundidad — dentro de una capa, determinada por la posición en el scene graph
- Las entidades sin sprites no se dibujan pero siguen existiendo en el mundo
Ve Scene Graph para más sobre capas y profundidad.