pyxen.Entity
Entityは軽量なハンドル — コンポーネントのコンテナです。
エンティティコンポーネントシステムの紹介はエンティティ&コンポーネントを参照してください。
組み込みコンポーネント
| コンポーネント | アクセス |
|---|---|
| Transform | e.x, e.y, e.rotation, e.scale |
| Sprite | e.sprite, e.color |
| Animation | e.animation |
| Sound | e.sound |
| Music | e.music |
| GridBody | e.body |
| GridMap | e.map |
| Node | e.parent, e.children |
| Layer | e.layer |
| Name | e.name |
| Camera | e.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")
プロパティ
| プロパティ | 型 | 説明 |
|---|---|---|
name | str | 現在のアニメーションクリップの名前 |
frame | int | クリップ内の現在のフレームインデックス |
playing | bool | アニメーションが再生中ならTrue |
finished | bool | ワンショットアニメーションが完了したら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")
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
property | str | — | プロパティ名(位置引数またはキーワード形式) |
to | float | — | 目標値 |
by | float | — | 相対オフセット(toの代替) |
start | float | 現在の値 | 開始値(デフォルトは現在の値) |
duration | float | 1.0 | 秒単位の継続時間 |
ease | str | "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から開始
アニメーション可能なプロパティ
| コンポーネント | プロパティ |
|---|---|
| Transform | x, y, rotation, sx, sy |
| Sprite | r, g, b, alpha |
| Camera | zoom |
イージング関数
| 名前 | カーブ |
|---|---|
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()
エンティティのTweenをキャンセルします。プロパティ名を渡すと1つのTweenをキャンセルし、引数なしで呼び出すとすべてのTweenをキャンセルします。値は現在の位置で固定されます。
entity.tweens.cancel("x") # 1つのプロパティをキャンセル
entity.tweens.cancel() # すべてキャンセル
競合の解決
同じエンティティとプロパティで新しいTweenを開始すると、前のものが置き換えられます。異なるプロパティのTweenは独立して実行されます。
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と並行して実行
破棄されたエンティティのTweenは自動的にクリーンアップされます。
プロパティで 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
パラメータ
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
*props | str | — | 1つ以上のプロパティ名(位置引数) |
by | float | — | 振幅(振動モード)。スピンの場合は省略。 |
center | float | 現在値 | 振動の中心値 |
speed | float | 1.0 | 角周波数(振動)または単位/秒(スピン) |
Tweenと同じ10個のプロパティ: x, y, rotation, sx, sy, r, g, b, alpha, zoom。
entity.animations.cancel()
エンティティのアニメーションをキャンセルします。プロパティ名を渡すと1つのアニメーションをキャンセルし、引数なしで呼び出すとすべてのアニメーションをキャンセルします。
entity.animations.cancel("rotation") # 1つのプロパティをキャンセル
entity.animations.cancel() # すべてキャンセル
親 / 子
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"):
...
マーカーコンポーネント
e.alive = True
マーカーはデータを保持しません — 存在のみを示します。通常のコンポーネントと同様にクエリできます:
for e in world.all("alive"):
...
コンポーネントフィールドへのアクセス
e.cell.row
e.cell.col
e.cell.row = 5
サポートされるフィールド型
| Python型 | 格納形式 |
|---|---|
int | 32ビット整数 |
float | 32ビット浮動小数点数 |
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
後続の割り当てでフィールドを省略するのは有効です — デフォルト値は0、0.0、False、""などになります。
コンポーネントの存在チェック
e.has("cell")
エンティティがそのコンポーネントを持っていればTrue、そうでなければFalseを返します。
カスタムと組み込みの両方のコンポーネント名で動作します:
e.has("sprite") # エンティティがスプライトを持っていればTrue
e.has("body") # エンティティがグリッドボディを持っていればTrue
子孫のクエリ
entity.all(*components, without=(), include_self=False)
エンティティの子孫すべて(シーングラフ階層を深さ優先で走査)のうち、指定のコンポーネントフィルタに一致するもののイテレータを返します。
world.all()と同様に動作しますが、ワールド全体ではなくサブツリーにスコープされます。
# "enemy"コンポーネントを持つすべての子孫
for e in parent.all("enemy"):
...
# 除外付き
for e in parent.all("enemy", without=("boss",)):
...
# 親エンティティ自身も含める
for e in parent.all("tag", include_self=True):
...
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
*components | str | — | 必須のコンポーネント名 |
without | tuple | () | 除外するコンポーネント名 |
include_self | bool | False | エンティティ自身を含めるかどうか |
組み込みとカスタムの両方のコンポーネント名に対応しています。
コンポーネントの削除
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()で破棄