7. ECSで作り直し

はじめに

ECS(Entity Component System)という設計スタイルのことを知ったので、ECSを使って、このヴァンサバ風ゲームを作り直してみます。

ECSとは?

Entity Component Systemの基本

構成要素 説明
Entity 識別用のID。見た目も中身も持たない「ただの番号」
Component データのまとまり(位置、速度、体力など)
System 複数のEntityを処理するロジック(移動、描画、AIなど)

ECSの特徴は「データとロジックを分離」と「責任の分離」 です。

  • EntityはID(number)のみです。
  • Componentはデータのみを持ち、ロジックは一切入れません。
  • Systemがロジックを受け持ちます。Phaserではupdateで毎フレーム呼び出されるものになります。

従来のオブジェクト指向との違い

オブジェクト指向 ECS
プレイヤー Playerクラスで位置・移動・描画を持つ Entity + PositionComponent + SpriteComponent + MovementSystem
継承 クラスを継承して機能追加 コンポーネントを付け替えて機能追加
柔軟性 低い(カチッとした構造) 高い(動的に機能を変えられる)

ヴァンサバ風ゲームに必要なECS構成

Phaser + TypeScriptで、ヴァンサバ風のトップビューゲームを作るとしたら、 以下のようなEntity / Component / System構成になります:

Entity(エンティティ)

  • Player : 操作するプレイヤーキャラクター。1体だけ存在
  • Enemy : 敵キャラ。大量に生成される
  • Projectile : 武器から発射される弾。敵に当たったり時間経過で消える
  • Item : ポーション、宝箱など

Component(コンポーネント)

  • SpriteComponent: 対応するSpriteへの参照
  • HealthComponent: HP、最大HPなど
  • PlayerInputComponent: プレイヤーの入力状態(上下左右)
  • WeaponComponent: 武器の種類、攻撃力、発射間隔、弾速など
  • ProjectileComponent: 弾のスピード、ダメージ、寿命など
  • EnemyComponent: 敵のスピード、ダメージ、種類など
  • TargetComponent: プレイヤーEntityID+追跡用オフセット

PositionComponent(位置)やVelocityComponent(移動速度)を作る方法もあるが、 Phaserのspriteで管理した方が簡単。

System(システム)

  • PlayerInputSystem: キー入力を読み取り、速度や方向を更新
  • RenderSystem: Spriteにアニメーションやエフェクトを反映
  • WeaponSystem: 一定間隔で弾を発射(武器ごとの発射管理)
  • ProjectileSystem: 弾の移動と寿命管理
  • EnemyAISystem: 敵がプレイヤーを追いかける処理
  • CollisionSystem: プレイヤー・敵・弾・壁などすべての衝突を管理
  • GameOverSystem: HPが0になったらゲームオーバー処理を発動

ECS以外の要素

その他、Manager(管理クラス)やEntity生成用のファクトリ関数も必要です。

  • ComponentManager.ts: 全Entityのコンポーネントを一括管理する静的マネージャ
  • EntityManager.ts: Entity(ID)の発行と削除を担当
  • GameConfig.ts: 定数定義
  • createPlayer.ts: プレイヤーEntityを生成し、必要なComponentを登録
  • createEnemy.ts: 敵Entityを生成し、必要なComponentを持たせる
  • createProjectile.ts: 弾Entityを生成し、速度やダメージなどを設定

まとめ

PlayerもEnemyもEntityでは単なるIDにすぎず、 PlayerクラスやEnemyクラスを作らないことに、最初は違和感がありました。

しかし、実際に作ってみると、Gameシーンでは、各Systemを初期化してUpdateで回すだけ。 各Systemが自分の担当範囲のことだけに集中できるので、全体として構造はかなりスッキリします。

今までの方法よりも開発がかなり速く進むようになり、おかげでかなり進みました。

実装したもの

  • マップ画像や敵キャラ画像のリニューアル
  • 敵キャラの追加(定期的にスポーン)
  • プレイヤーの攻撃
  • ゲームオーバー処理
  • アセットローディング処理