pyxen.Entity

Entity 是一个轻量级句柄——组件的容器。

有关实体组件系统的介绍,请参见实体与组件


内置组件

组件访问方式
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)

读取 scale 返回一个 Vector2

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

Sprite

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

读取 color 返回一个 Color

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

精灵动画

当使用 animation 参数创建精灵时,引擎会自动播放动画。你可以通过 e.animation 读取动画状态:

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

属性

属性类型描述
namestr当前动画片段的名称
frameint片段内的当前帧索引
playingbool动画正在播放时为 True
finishedbool一次性动画播放完成时为 True
anim = player.animation
if anim:
    print(anim.name)      # "walk"
    print(anim.frame)     # 2
    print(anim.playing)   # True
    print(anim.finished)  # False

如果没有活动动画,e.animation 返回 None

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

取消

e.animation 设为 None 以停止播放:

player.animation = None

赋值新的精灵会自动取消任何现有动画。

一次性动画

使用 loop=False 播放只执行一次的动画:

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 可以随时间平滑地动画化实体的属性。引擎自动处理插值——无需逐帧编写代码。

entity.tween()

# 指定属性名形式
entity.tween("x", to=200, duration=1.0)
entity.tween("alpha", to=0, duration=0.5, ease="out_quad")

# 关键字简写形式——同时动画多个属性
entity.tween(x=200, y=100, duration=1.0, ease="out_quad")
参数类型默认值描述
propertystr属性名称(位置参数或关键字形式)
tofloat目标值
byfloat相对偏移量(to 的替代)
startfloat当前值起始值(默认为当前值)
durationfloat1.0持续时间(秒)
easestr"linear"缓动函数名称

使用 to 指定绝对目标值,或 by 指定相对偏移量:

entity.tween("x", to=200, duration=1.0)    # 移动到 x=200
entity.tween("x", by=50, duration=0.5)     # 向右移动 50 像素

使用 start 覆盖起始值:

entity.tween("x", to=200, start=0, duration=1.0)  # 始终从 0 开始

可动画属性

组件属性
Transformx, y, rotation, sx, sy
Spriter, g, b, alpha
Camerazoom

缓动函数

名称曲线
linear匀速(默认)
in_quad慢启动,加速
out_quad快启动,减速
in_out_quad慢启动和结束
in_cubic比 quad 更慢的启动
out_cubic比 quad 更快的启动
in_out_cubic平滑的慢启动和结束
in_expo非常慢的启动,爆发式加速
in_out_expo中段爆发
out_expo非常快的启动,柔和停止
in_back先后退再前进
out_back超越目标后回落
in_out_back后退和超越
in_elastic弹性蓄力
out_elastic弹性超越和弹跳
in_out_elastic两端弹性

entity.tweens.cancel()

取消实体的 tweens。传递属性名称可取消单个 tween,不传参数则取消所有 tweens。值冻结在当前位置。

entity.tweens.cancel("x")   # 取消一个属性
entity.tweens.cancel()       # 取消所有

冲突解决

在同一实体和属性上启动新的 tween 会替换之前的。不同属性的 tweens 独立运行。

entity.tween("x", to=100, duration=1.0)
entity.tween("x", to=200, duration=0.5)  # 替换第一个 tween
entity.tween("y", to=50, duration=1.0)   # 与 x 的 tween 并行运行

已销毁实体上的 tweens 会自动清理。

在属性上启动 animate() 会取消该属性上任何活动的 tween(),反之亦然。


动画

无限运行的连续动画 — 正弦波振荡(脉冲、呼吸、摆动)和恒速旋转。

entity.animate() — 振荡

使用正弦波围绕中心值振荡属性。

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

值遵循:center + sin(elapsed * speed) * by

entity.animate() — 旋转

以恒定速率累积值。省略 by= 以使用旋转模式。

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

参数

参数类型默认值描述
*propsstr一个或多个属性名(位置参数)
byfloat振幅(振荡模式)。旋转时省略。
centerfloat当前值振荡的中心值
speedfloat1.0角频率(振荡)或单位/秒(旋转)

与 tweens 相同的 10 个属性:x, y, rotation, sx, sy, r, g, b, alpha, zoom

entity.animations.cancel()

取消实体上的动画。传递属性名称可取消单个动画,不传参数则取消所有动画。

entity.animations.cancel("rotation")   # 取消一个属性
entity.animations.cancel()             # 取消所有

Parent / Children

child.parent = parent

访问子节点:

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

获取子节点数量:

parent.children.count

自定义组件

组件通过赋值创建:

  • 字典——结构化组件
  • 布尔值——标记组件
e.cell = {
    'row': 0,
    'col': 0
}

第一次赋值创建模式。字段类型会被推断,模式一旦确定就固定了——之后无法添加新字段。


在系统中使用组件

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

参见:pyxen.world.all()


标记组件

e.alive = True

标记不存储数据——它们仅表示存在。像普通组件一样查询:

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

访问组件字段

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

支持的字段类型

Python 类型存储为
int32 位整数
float32 位浮点数
bool布尔值
str固定字符串(最多 31 字符)
Entity实体引用

无效类型会抛出:

TypeError: invalid value type in dict

模式规则

  • 最大组件大小:256 字节
  • 字符串最多:31 个字符
  • 字典键必须是字符串
  • 模式创建后无法添加新字段
e.cell = {'row': 0}
e.cell = {'row': 0, 'new_field': 5}
ValueError: cannot create new fields after schema is complete

后续赋值时可以省略字段——它们会默认为 00.0False"" 等。


检查组件

e.has("cell")

如果实体拥有该组件返回 True,否则返回 False

这对自定义和内置组件名称都有效:

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

查询后代

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

返回实体所有后代的迭代器(通过场景图层级进行深度优先遍历),匹配给定的组件过滤器。

工作方式与 world.all() 完全相同,但范围限定在子树而非整个世界。

# 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):
    ...
参数类型默认值描述
*componentsstr要求的组件名称
withouttuple()要排除的组件名称
include_selfboolFalse是否包含实体本身

支持内置和自定义组件名称。


移除组件

使用 del 或赋值 None 来移除实体上的组件:

# 两种方式等效:
del entity.health
entity.health = None

移除后,entity.has("health") 返回 False,该实体不再匹配对该组件的查询。

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

del e.health

e.has("health")         # False
# world.all("health") 不会包含 e

你可以在移除后重新添加组件:

del e.health
e.health = {'hp': 50}   # 正常工作

内置组件

所有内置组件都可以移除:

del e.sprite    # 清除精灵数据
del e.body      # 清除物理碰撞体
del e.camera    # 移除摄像机
del e.text      # 移除文本
del e.sound     # 移除音效
del e.music     # 移除音乐
del e.map       # 移除网格地图

Sprite 和 body 会被零初始化(实体仍保留存储空间,但数据为空)。Camera、text、sound、music 和 map 会被完全擦除。

标记

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

实体生命周期

  • 通过 world.spawn() 创建
  • 通过组件赋值修改
  • 通过 del= None 移除组件
  • 通过 world.destroy() 销毁

参见:pyxen.world.spawn() | pyxen.world.destroy()