前書き
エンティティコンポーネントシステムは、オブジェクト指向のアーキテクチャ手法です。
オブジェクト指向プログラミングと同じように、この用語の意味についての普遍的な合意はありません。ただし、エンティティコンポーネントシステムは、継承のアーキテクチャ上の代替として特に意図されていることは明らかです。継承階層はオブジェクトが何であるかを表現するのに自然ですが、特定の種類のソフトウェア(ゲームなど)では、オブジェクトが何をするかをむしろ表現します。
これは、C ++またはJavaでの作業に慣れている可能性が高い「クラスと継承」とは異なるオブジェクトモデルです。エンティティは、JavaScriptやSelfのプロトタイプのように、クラスと同じくらい表現力があります。これらのシステムはすべて相互に実装できます。
例
言おうPlayer
とするエンティティであるPosition
、Velocity
とKeyboardControlled
明らかに物事を行うコンポーネントを、。
entity Player:
Position
Velocity
KeyboardControlled
私たちは知っているPosition
の影響を受けなければなりませんVelocity
、とVelocity
によりますKeyboardControlled
。問題は、これらの効果をどのようにモデル化するかです。
エンティティ、コンポーネント、およびシステム
コンポーネントが相互に参照していないと仮定します。外部Physics
システムはすべてのVelocity
コンポーネントを走査しPosition
、対応するエンティティのを更新します。Input
このシステムは、すべての横断KeyboardControlled
コンポーネントとアップデートVelocity
。
Player
+--------------------+
| Position | \
| | Physics
/ | Velocity | /
Input | |
\ | KeyboardControlled |
+--------------------+
これは基準を満たします:
システムは現在のイベントを処理し、責任ある制定コンポーネントによって記述行動を。また、衝突などのエンティティ間の相互作用の処理も担当します。
エンティティとコンポーネント
しかし、コンポーネントがあるとしませんお互いへの参照を持っています。エンティティは、いくつかのコンポーネントを作成し、それらを一緒にバインドし、それらのライフタイムを管理する単なるコンストラクタです。
class Player:
construct():
this.p = Position()
this.v = Velocity(this.p)
this.c = KeyboardControlled(this.v)
エンティティは、入力および更新イベントをそのコンポーネントに直接ディスパッチする可能性があります。Velocity
更新にKeyboardControlled
応答し、入力に応答します。これはまだ基準を満たしています:
ここで、コンポーネントの相互作用は明示的であり、システムによって外部から課されるものではありません。動作を説明するデータ(速度の量は?)と、それを実行するコード(速度は?)は結合されていますが、自然な形です。データは、動作に対するパラメータとして表示できます。また、一部のコンポーネントはまったく動作しません。a は場所Position
にいるという動作です。
相互作用は、エンティティのレベル(「… Player
と衝突する場合Enemy
」)または個々のコンポーネントのレベル(「… Life
とエンティティが衝突する場合Strength
」)で処理できます。
構成部品
エンティティが存在する理由は何ですか?単なるコンストラクターである場合は、コンポーネントのセットを返す関数に置き換えることができます。後でタイプでエンティティをクエリしたい場合は、それを可能にするTag
コンポーネントを用意することもできます。
function Player():
t = Tag("Player")
p = Position()
v = Velocity(p)
c = KeyboardControlled(v)
return {t, p, v, c}
エンティティタイプからイベントを完全に分離し、抽象クエリによって相互作用を処理する必要があります。クエリするエンティティタイプはこれ以上ありませんTag
。デバッグには、ゲームロジックよりも任意のデータを使用する方がおそらく良いでしょう。
結論
エンティティは、関数、ルール、アクター、またはデータフローコンビネーターではありません。それらは、具体的な現象をモデル化する名詞です。つまり、オブジェクトです。Wikipediaが言うように、エンティティーコンポーネントシステムは、一般的なオブジェクトをモデリングするためのソフトウェアアーキテクチャパターンです。