その1:https://qiita.com/mas-yo/items/43101d2e5ef073a1f3f5
その2:https://qiita.com/mas-yo/items/f802b5a6a6b3f47eed71
その3:https://qiita.com/mas-yo/items/cd0ddfebba3348a98b24
その4:https://qiita.com/mas-yo/items/c10ee3c8939ead6aec71
前回は、ECSで設計した見下ろし型アクションゲームの土台に、「空を飛ぶ敵」を追加で実装する、ということを想定して、設計を考えてみました。
このように、MoveAttribute
コンポーネントを追加することで、空を飛ぶ状態を表現したのでした。
さて、次に、「羽のアイテムを使うとプレイヤーは空を飛べるようにする」これを設計してみましょう。
UseItem
コンポーネント、MoveAttribute
システム
まず新たなコンポーネントとして、アイテムの使用状態を持つUseItem
コンポーネントを考えます。
アイテムを使う、というのは一般にプレイヤーの入力によって決まりますが、ここでは詳細は省略します。
今回の仕様では、UseItem
に依存してMoveAttribute
が変わればOK、ということになりますね。
よって、MoveAttribute
システムを追加し、UseItem
を参照するようにします。
MoveAttribute
の更新は、MoveAttribute
システムが担当します。
前回(詳細は省きましたが)、MoveAttribute
は何らかのマスターデータを参照して、敵が「空を飛ぶか、地面を歩くか」を決める、ということを想定していました。
今回は、それに加えて、UseItem
が「羽アイテムを使う」という状態だったときに、MoveAttribute
を「飛行」に設定します。
この様に、当初は静的な情報により決定される挙動が、動的なものに変えられたとしても、大きな影響なく、実装をすることができます。
オブジェクト指向による設計と比較すると、どうでしょうか。
その1で、オブジェクト指向で設計した際、「空を飛ぶ」かどうかは、クラスによって決まっていました。よって、後から動的に空を飛べるようになる機能が欲しくなった際に、困ってしまいましたね。
今回はECSの設計によって、それをうまく回避できています。
まとめ
以上、全5回に渡って、オブジェクト志向による設計の欠点と、それをECSによってどのように克服できるかについて、見てきました。
プログラミングを学ぶとき、多くの方は、手続き型から、オブジェクト指向と学んで来たと思います。
オブジェクト指向による設計は、現実世界に即して考えるのでわかりやすいですが、一度設計したクラスを後から簡単には変えられないため、常に仕様変更・機能追加を繰り返すゲームのプログラミングには、向かない面もあります。
そこに、データ志向設計(=Entity Component System)が注目されている理由もあります。
ECSによる柔軟でバグを生みにくいプログラム設計をして、みんなで幸せになりましょう。
ECSでゲームをつくるとどんな感じになるのか、
https://github.com/mas-yo/rust-ecs-game
こちらで実験しています。(言語はRustです)
興味のある方はご覧になってください。