というわけでボスキャラクターを作っています。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
、一定の軌道を動き回るリフトなどを表すのに便利なKinematicPositionBased
やKinematicVelocityBased
があります -
Velocity
物体の速度。これは直接指定するというより、外力や他の物体との衝突によって物理エンジンが決定する感じになります -
Collider
物体の形状を表します。ここではball
なので円形です。 -
ExternalForce
外力。これを設定するとエンティティを力で押すことになり、つまりその力の方向にこのエンティティが動くようになります。
このほかに、さらにこの親エンティティの子として別のエンティティを追加し、そこに AseSpriteAnimation
やTransform
で
ボスキャラクター本体の画像を表示しています。この子のコンポーネントのY座標を調整することで、影の位置はそのままでボスキャラクターの画像のY座標だけ大きくし、ジャンプしているように見せています。
こんな感じで多数のコンポーネントの集合体としてエンティティを定義するのが Bevy の Entity Component Systemです。クラスや継承、オブジェクトコンポジションを主体にオブジェクトを構築するオブジェクト指向ベースのゲームエンジンとはかなり雰囲気が異なることがわかると思います。