2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🦀ひとりRustとBevyでゲーム開発🕊️Advent Calendar 2024

Day 12

【Rustのまほう2】#10 敵キャラクターの構造

Last updated at Posted at 2024-12-11

というわけでボスキャラクターを作っています。Bevy Engineにおける敵キャラクターももちろんひとつのエンティティで、多数のコンポーネントの集合体になっています。Bevyでの開発の雰囲気をお見せしたいと思いますが、以下がボスキャラクターの実際のコードです。コンポーネントのプロパティ部分は省略してあります。

commands
    .spawn((
        Name::new("huge slime"),
        StateScoped(GameState::InGame),
        Enemy,
        Life { .. },
        HugeSlime { .. },
        Actor { .. },
        ActorState::default(),
        EntityDepth,
        AseSpriteAnimation { .. },
        Transform::from_translation( .. ),
        (
            RigidBody::Dynamic,
            Velocity { .. },
            Collider::ball(24.0),
            GravityScale(0.0),
            LockedAxes::ROTATION_LOCKED,
            Damping { .. },
            ExternalForce::default(),
            ExternalImpulse::default(),
            ActiveEvents::COLLISION_EVENTS,
            CollisionGroups::new( .. ),
        ),
    ))
    .with_children(|parent| {
        parent.spawn((
            HugeSlimeSprite,
            AseSpriteAnimation { .. },
            Transform::from_xyz( .. ),
        ));
    });

各コンポーネントの役割は以下のようになっています。全部は紹介しきれないので主要なものだけ。

  • Name エンティティの名前。名前を付けてインスペクタで覗いたときに見つけやすいようにしてます
  • StateScoped このエンティティをInGameステートでだけ存在するようにしていしています。これでタイトル画面に戻ったときにこのエンティティは自動的に削除されます。
  • Enemy 敵キャラクターであることを識別するための独自のコンポーネント。こういうプロパティは持たないがエンティティの種類を識別するためのコンポーネントをマーカーコンポーネントなんて読んだりすることもあります。
  • Life 攻撃がヒットするヒットポイントが減るという動作をするエンティティを表します。敵キャラクターだけではなく、背景の本棚やランタンなどの物体にもこれが設定されており、攻撃すると壊れて消滅するようになっています。
  • HugeSlime このボスキャラクター特有のプロパティを定義しています。たとえばこのボスキャラクターは一定時間ごとに飛び跳ねるので、今飛んでいる状態なのかどうかを表していたりします。
  • EntityDepth 奥行を調整するエンティティを表すコンポーネント。このゲームは2Dですが、前後の重なりはZ座標で指定します。そしてキャラクターは画面上方向ほど奥なので、Y座標が大きくなるとそれに伴ってZ座標は小さくなる、という調整が必要になりますが、その調整をするエンティティを表しています
  • AseSpriteAnimation ボスキャラクターの影の画像です
  • Transform ボスキャラクターの位置です。ボスキャラクターを移動させるときに、このコンポーネントのプロパティを直接変更することはないです。ExternalForceコンポーネントを変更して外力を与え、物理エンジンがそれを計算してTransformコンポーネントに結果を書きこむことでキャラクターが移動します。

以下は物理エンジン関係のコンポーネントです。

  • RigidBody 剛体の種類を表します。普通の動く物体を表すDynamicの他にも、壁など動かない物体を表すFixed、一定の軌道を動き回るリフトなどを表すのに便利なKinematicPositionBasedKinematicVelocityBasedがあります
  • Velocity 物体の速度。これは直接指定するというより、外力や他の物体との衝突によって物理エンジンが決定する感じになります
  • Collider 物体の形状を表します。ここではballなので円形です。
  • ExternalForce 外力。これを設定するとエンティティを力で押すことになり、つまりその力の方向にこのエンティティが動くようになります。

このほかに、さらにこの親エンティティの子として別のエンティティを追加し、そこに AseSpriteAnimationTransform
ボスキャラクター本体の画像を表示しています。この子のコンポーネントのY座標を調整することで、影の位置はそのままでボスキャラクターの画像のY座標だけ大きくし、ジャンプしているように見せています。

こんな感じで多数のコンポーネントの集合体としてエンティティを定義するのが Bevy の Entity Component Systemです。クラスや継承、オブジェクトコンポジションを主体にオブジェクトを構築するオブジェクト指向ベースのゲームエンジンとはかなり雰囲気が異なることがわかると思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?