pyxen.Entity

An Entity is a lightweight handle — a container for components.

For an introduction to the entity-component system, see Entities and Components.


Built-in Components

ComponentAccess
Transforme.x, e.y, e.rotation, e.scale
Spritee.sprite, e.color
Animatione.animation
Sounde.sound
Musice.music
GridBodye.body
GridMape.map
Nodee.parent, e.children
Layere.layer
Namee.name
Camerae.camera

Transform

e.x = 100
e.y = 50
e.rotation = 45
e.scale = (2, 2)

Reading scale returns a Vector2:

s = e.scale
print(s.x, s.y)

Sprite

e.sprite = sprite
e.color = (1.0, 0.5, 0.5, 1.0)

Reading color returns a Color:

c = e.color
print(c.r, c.g, c.b, c.a)

Sprite Animation

When a sprite is created with the animation parameter, the engine plays the animation automatically. You can read the animation state via e.animation:

player.sprite = Sprite("hero", animation="walk")

Properties

PropertyTypeDescription
namestrName of the current animation clip
frameintCurrent frame index within the clip
playingboolTrue if the animation is actively playing
finishedboolTrue if a one-shot animation has completed
anim = player.animation
if anim:
    print(anim.name)      # "walk"
    print(anim.frame)     # 2
    print(anim.playing)   # True
    print(anim.finished)  # False

If no animation is active, e.animation returns None:

player.sprite = Sprite("hero", tile=(0, 0, 16, 16))
print(player.animation)  # None

Cancelling

Set e.animation to None to stop playback:

player.animation = None

Assigning a new sprite automatically cancels any existing animation.

One-shot animations

Use loop=False for animations that play once:

player.sprite = Sprite("hero", animation="attack", loop=False)

def update():
    if player.animation and player.animation.finished:
        player.sprite = Sprite("hero", animation="idle")

Tweens

Tweens smoothly animate an entity’s properties over time. The engine handles interpolation automatically — no per-frame code needed.

entity.tween()

# Named property form
entity.tween("x", to=200, duration=1.0)
entity.tween("alpha", to=0, duration=0.5, ease="out_quad")

# Keyword shorthand — animate multiple properties at once
entity.tween(x=200, y=100, duration=1.0, ease="out_quad")
ParameterTypeDefaultDescription
propertystrProperty name (positional, or use keyword form)
tofloatTarget value
byfloatRelative offset (alternative to to)
startfloatcurrentStart value (defaults to the property’s current value)
durationfloat1.0Duration in seconds
easestr"linear"Easing function name

Use to for an absolute target, or by for a relative offset:

entity.tween("x", to=200, duration=1.0)    # move to x=200
entity.tween("x", by=50, duration=0.5)     # move 50 pixels to the right

Use start to override the starting value:

entity.tween("x", to=200, start=0, duration=1.0)  # always start from 0

Tweennable Properties

ComponentProperties
Transformx, y, rotation, sx, sy
Spriter, g, b, alpha
Camerazoom

Easing Functions

NameCurve
linearConstant speed (default)
in_quadSlow start, accelerating
out_quadFast start, decelerating
in_out_quadSlow start and end
in_cubicSlower start than quad
out_cubicFaster start than quad
in_out_cubicSmooth slow start and end
in_expoVery slow start, explosive acceleration
in_out_expoExplosive middle
out_expoVery fast start, gentle stop
in_backPulls back before moving forward
out_backOvershoots target, then settles
in_out_backPull back and overshoot
in_elasticElastic wind-up
out_elasticElastic overshoot and bounce
in_out_elasticElastic on both ends

entity.tweens.cancel()

Cancel tweens on an entity. Pass a property name to cancel a single tween, or call with no arguments to cancel all tweens. The value freezes at its current position.

entity.tweens.cancel("x")   # cancel one property
entity.tweens.cancel()       # cancel all

Conflict Resolution

Starting a new tween on the same entity and property replaces the previous one. Tweens on different properties run independently.

entity.tween("x", to=100, duration=1.0)
entity.tween("x", to=200, duration=0.5)  # replaces the first tween
entity.tween("y", to=50, duration=1.0)   # runs alongside the x tween

Tweens on destroyed entities are automatically cleaned up.

Starting an animate() on a property cancels any active tween() on that property, and vice versa.


Animations

Continuous animations that run indefinitely — sine-wave oscillation (pulsing, breathing, bobbing) and constant-rate spinning.

entity.animate() — Oscillate

Oscillate a property around a center value with a sine wave.

entity.animate("sx", "sy", by=0.15, speed=6.0)     # coin pulse
entity.animate("alpha", by=0.3, center=0.7, speed=4.0)  # flicker 0.4–1.0

The value follows: center + sin(elapsed * speed) * by

entity.animate() — Spin

Accumulate a value at a constant rate. Omit by= to use spin mode.

entity.animate("rotation", speed=180)   # 180°/sec clockwise

Parameters

ParameterTypeDefaultDescription
*propsstrOne or more property names (positional)
byfloatAmplitude (oscillate mode). Omit for spin.
centerfloatcurrentCenter value for oscillation
speedfloat1.0Angular frequency (oscillate) or units/sec (spin)

Same 10 properties as tweens: x, y, rotation, sx, sy, r, g, b, alpha, zoom.

entity.animations.cancel()

Cancel animations on an entity. Pass a property name to cancel a single animation, or call with no arguments to cancel all animations.

entity.animations.cancel("rotation")   # cancel one property
entity.animations.cancel()             # cancel all

Parent / Children

child.parent = parent

Access children:

for c in parent.children:
    print(c.name)

Get child count:

parent.children.count

Custom Components

Components are created by assigning:

  • A dictionary — structured component
  • A boolean — marker component
e.cell = {
    'row': 0,
    'col': 0
}

The first assignment creates the schema. Field types are inferred and the schema becomes fixed — you cannot add new fields later.


Using Components in Systems

for cell in world.all("cell"):
    ...

See: pyxen.world.all()


Marker Components

e.alive = True

Markers store no data — they only indicate presence. Query them like normal components:

for e in world.all("alive"):
    ...

Accessing Component Fields

e.cell.row
e.cell.col
e.cell.row = 5

Supported Field Types

Python TypeStored As
int32-bit integer
float32-bit float
boolBoolean
strFixed string (max 31 chars)
EntityEntity reference

Invalid types raise:

TypeError: invalid value type in dict

Schema Rules

  • Max component size: 256 bytes
  • Strings max: 31 characters
  • Dict keys must be strings
  • Cannot add new fields after schema creation
e.cell = {'row': 0}
e.cell = {'row': 0, 'new_field': 5}
ValueError: cannot create new fields after schema is complete

It’s valid to omit fields on subsequent assignments — they default to 0, 0.0, False, "", etc.


Checking for a Component

e.has("cell")

Returns True if the entity has the component, False otherwise.

This works for both custom and built-in component names:

e.has("sprite")   # True if the entity has a sprite
e.has("body")     # True if the entity has a grid body

Querying Descendants

entity.all(*components, without=(), include_self=False)

Returns an iterator over all descendants of the entity (depth-first through the scene graph hierarchy) that match the given component filter.

Works exactly like world.all(), but scoped to a subtree instead of the entire world.

# All descendants with "enemy" component
for e in parent.all("enemy"):
    ...

# With exclusion
for e in parent.all("enemy", without=("boss",)):
    ...

# Include the parent entity itself
for e in parent.all("tag", include_self=True):
    ...
ParameterTypeDefaultDescription
*componentsstrComponent names to require
withouttuple()Component names to exclude
include_selfboolFalseWhether to include the entity itself

Both built-in and custom component names are supported.


Removing Components

Remove a component from an entity using del or by assigning None:

# Both are equivalent:
del entity.health
entity.health = None

After removal, entity.has("health") returns False and the entity no longer matches queries for that component.

e = world.spawn()
e.health = {'hp': 100}

del e.health

e.has("health")         # False
# world.all("health") won't include e

You can re-add a component after removing it:

del e.health
e.health = {'hp': 50}   # works fine

Built-in components

All built-in components can be removed:

del e.sprite    # clears sprite data
del e.body      # clears physics body
del e.camera    # removes camera
del e.text      # removes text
del e.sound     # removes sound
del e.music     # removes music
del e.map       # removes grid map

Sprite and body are zero-initialized (the entity still has the storage, but the data is empty). Camera, text, sound, music, and map are fully erased.

Markers

e.enemy = True
del e.enemy      # or: e.enemy = None
e.has("enemy")   # False

Entity Lifecycle

  • Created with world.spawn()
  • Modified via component assignment
  • Components removed with del or = None
  • Destroyed with world.destroy()

See: pyxen.world.spawn() | pyxen.world.destroy()