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:

ComponentePropósito
TransformPosición (x, y), rotación, escala
SpriteApariencia visual — imagen, tile, pivote, color
CameraViewport con zoom
GridBodyCuerpo de colisión en la cuadrícula
GridMapTilemap con filas, columnas y datos de tiles
SoundReproducción de efectos de sonido
MusicReproducción de flujo de música
NameIdentificador de texto para búsqueda
LayerCapa de renderizado (0-255)
Parent / ChildrenJerarquí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:

TipoEjemploNotas
int42Entero de 32 bits
float3.14Flotante de 32 bits
boolTrueBooleano
str"hello"Máximo 31 caracteres
EntityplayerReferencia 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: