スプライト&レンダリング

PyxenはMetalベースの2Dレンダラーを使ってゲームを描画します。画面上に表示されるものはすべて、Spriteコンポーネントを持つエンティティです。

スプライト

スプライトは、エンティティに何を描画するかをエンジンに伝えます。プロジェクトの画像を参照して作成します:

player = world.spawn(sprite=Sprite("hero"))

文字列"hero"はプロジェクトのアセットにあるheroという名前の画像を参照します。

タイルシート

多くのゲームではタイルシート — 複数のフレームやタイルがグリッド状に配置された1枚の画像を使います。tileパラメータで画像の領域を選択します:

Sprite("characters", tile=(0, 0, 16, 16))    # 最初のタイル
Sprite("characters", tile=(16, 0, 16, 16))   # 2番目のタイル
Sprite("characters", tile=(0, 16, 16, 16))   # 2行目のタイル

4つの値は画像の左上からピクセル単位で計測した(x, y, width, height)です。

スプライトアニメーション

スプライトエディタで名前付きアニメーションを作成すれば、直接再生できます:

player = world.spawn(
    sprite=Sprite("hero", animation="walk"),
    x=100, y=50
)

エンジンはスプライトのメタデータからアニメーションのフレームシーケンスとFPSを読み取り、フレームを自動的に進めます。アニメーションを切り替えるには、新しいスプライトを割り当てます:

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

ワンショットアニメーション(攻撃や死亡など)には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")

e.animationコンポーネントは現在の状態への読み取り専用アクセスを提供します:.name.frame.playing.finished。詳細はEntityリファレンスを参照してください。

タイルをフレームごとに変更して手動でアニメーションすることもできます:

def update():
    frame = time.frame % 4
    player.sprite = Sprite("hero", tile=(frame * 16, 0, 16, 16))

ピボットポイント

デフォルトでは、スプライトは左上隅から描画されます。ピボットポイントを変更して、スプライトのアンカー位置を制御できます:

Sprite("hero", tile=(0, 0, 16, 16), pivot=(8, 8))

これにより、スプライトはエンティティの位置を中心に配置されます。ピボットはタイルに対するピクセル座標です。ピボットをタイルの中心に設定するのが最も一般的な選択です — 回転やスケーリングが直感的に動作するようになります。

カラーティンティング

エンティティのスプライトにカラーを設定して色を付けることができます:

player.color = (1.0, 0.5, 0.5, 1.0)  # 赤みがかった色

カラーは0.0から1.0の値を持つRGBAタプルです。白(1, 1, 1, 1)はティンティングなしを意味します。アルファチャンネルで透明度を設定できます:

ghost.color = (1, 1, 1, 0.5)  # 50%透明

Tweensを使ってカラーやアルファをスムーズにアニメーションすることもできます:

ghost.tween("alpha", to=0, duration=0.5, ease="out_quad")  # フェードアウト

カメラ

カメラはワールドのどの部分が見えるかを制御します。Cameraコンポーネントを持つエンティティを生成して作成します:

cam = world.spawn(camera=Camera(), x=160, y=90)

カメラを移動してプレイヤーを追従させます:

def update():
    cam.x = player.x
    cam.y = player.y

カメラはズームに対応しています:

cam.camera.zoom = 2.0  # 2倍にズームイン

Tweenでズームをスムーズにアニメーションできます:

cam.tween("zoom", to=2.0, duration=0.5, ease="out_quad")

解像度

Pyxenのゲームはデフォルトで320x180ピクセルの解像度で動作します。これは意図的な選択です — 低解像度はピクセルアートをシャープに見せ、レンダリングを高速に保ちます。エンジンが出力を画面いっぱいにスケーリングします。

テキスト

Textコンポーネントはビットマップテキストをレンダリングします。テキストエンティティは次のように作成します:

label = world.spawn(text=Text("Hello, world!"))

デフォルトでは組み込みのピクセルフォントが使用されます。フォントエディタで作成したカスタムフォントを使用するには:

title = world.spawn(text=Text("Game Over", font="myfont"))

実行時にテキストを更新するには、textプロパティを変更します:

def update():
    score_label.text = Text(f"Score: {score}")

完全なAPIはTextリファレンスを参照してください。

描画順序

エンティティは以下の順序で描画されます:

  1. レイヤー — 低いレイヤーが先に描画(レイヤー0がレイヤー1の後ろ)
  2. 深度 — レイヤー内では、シーングラフの位置で決定
  3. スプライトのないエンティティは描画されませんが、ワールドに存在し続けます

レイヤーと深度の詳細はシーングラフを参照してください。

完全なSprite APIはSpriteCameraを参照してください。