Entidades y componentes
Pyxen usa un Sistema de Entidades y Componentes (ECS). Si has usado motores de juegos con jerarquías de clases — donde un Player extiende Character extiende GameObject — esto es diferente. En Pyxen, no hay herencia. Todo es composición.
Entidades
Una entidad es un objeto de juego. Puede ser un jugador, una pared, una bala, una partícula — cualquier cosa. Internamente, una entidad es solo un ID. No contiene datos por sí misma. En cambio, le adjuntas componentes.
player = world.spawn(name="player", x=100, y=50)
Esto crea una entidad en la posición (100, 50) con un nombre. La entidad existe en el mundo y será renderizada si tiene un sprite.
Componentes
Los componentes son piezas de datos adjuntas a una entidad. Pyxen tiene dos tipos:
Componentes integrados
Estos los proporciona el motor:
| Componente | Propósito |
|---|---|
| Transform | Posición (x, y), rotación, escala |
| Sprite | Apariencia visual — imagen, tile, pivote, color |
| Camera | Viewport con zoom |
| GridBody | Cuerpo de colisión en la cuadrícula |
| GridMap | Tilemap con filas, columnas y datos de tiles |
| Sound | Reproducción de efectos de sonido |
| Music | Reproducción de flujo de música |
| Name | Identificador de texto para búsqueda |
| Layer | Capa de renderizado (0-255) |
| Parent / Children | Jerarquía de escena |
Configuras componentes integrados a través de propiedades de entidad o al momento de generar:
e = world.spawn(
x=50, y=80,
sprite=Sprite("hero"),
name="player"
)
# después
e.x = 100
e.sprite = Sprite("hero", tile=(16, 0, 16, 16))
Componentes personalizados
Puedes adjuntar tus propios componentes a cualquier entidad. Un componente personalizado es un diccionario con campos tipados:
player.health = {"value": 100, "max": 100}
player.speed = {"value": 2.5}
Una vez adjuntados, accedes a los campos directamente:
player.health.value -= 10
También puedes usar componentes marcadores — componentes sin datos que actúan como etiquetas:
player.alive = True
enemy.boss = True
Esto es útil para consultas: puedes encontrar todas las entidades con un marcador dado.
Tipos de campo
Los campos de componentes pueden ser:
| Tipo | Ejemplo | Notas |
|---|---|---|
int | 42 | Entero de 32 bits |
float | 3.14 | Flotante de 32 bits |
bool | True | Booleano |
str | "hello" | Máximo 31 caracteres |
| Entity | player | Referencia a otra entidad |
Estas restricciones existen porque los componentes se almacenan en un layout compacto y eficiente dentro del motor C++. Esto es lo que hace las consultas rápidas.
Consultar entidades
El mundo te permite encontrar entidades por sus componentes:
# todas las entidades con un componente "health"
for e in world.all("health"):
if e.health.value <= 0:
world.destroy(e)
# combinar: tiene "enemy", no tiene "dead"
for e in world.all("enemy", without=("dead",)):
e.x += e.speed.value
También puedes consultar por componentes integrados como "sprite", "body", "camera", "sound", "music" y "map":
# todas las entidades con un sprite
for e in world.all("sprite"):
e.color = (1, 1, 1, 1)
# entidades con sprite y el componente personalizado "enemy"
for e in world.all("sprite", "enemy"):
e.color = (1, 0, 0, 1)
Las consultas son la forma principal de escribir lógica de juego en Pyxen. En vez de que cada objeto se actualice a sí mismo, escribes sistemas que iteran sobre entidades con componentes específicos.
Ve la API completa: world.all(), Entity
¿Por qué ECS?
Si estás acostumbrado al código de juego orientado a objetos, ECS puede parecer inusual al principio. Los beneficios:
- Sin jerarquías de clases — no necesitas decidir de antemano si un PowerUp es-un Collectible es-un Entity. Solo adjunta los componentes que necesitas.
- Fácil combinar comportamientos — una entidad puede tener componentes
health,enemy,flyingybosstodos a la vez, sin herencia múltiple. - Consultas rápidas — el motor almacena componentes en memoria contigua, así que iterar sobre todas las entidades con un componente dado es muy eficiente.
- Fácil de depurar — cada entidad es solo una bolsa de datos. El inspector de fotogramas te muestra exactamente qué está adjunto a cada una.