最近、「エンティティシステム」を使用してシンプルなSpace Invadorsゲームを作成しました。これは、属性と動作を非常にうまく分離するパターンです。それを完全に理解するのに数回の反復が必要でしたが、設計されたいくつかのコンポーネントを取得すると、既存のコンポーネントを使用して新しいオブジェクトを作成することが非常に簡単になります。
あなたはこれを読むべきです:
http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/
それは非常に知識のある人によって頻繁に更新されます。また、具体的なコード例を含む唯一のエンティティシステムの説明でもあります。
私の反復は次のようになりました:
最初の反復には、Adamの説明どおりの「EntitySystem」オブジェクトがありました。しかし、私のコンポーネントにはまだメソッドがありました。「レンダリング可能な」コンポーネントにはpaint()メソッドがあり、positionコンポーネントにはmove()メソッドなどがありました。エンティティを具体化し始めたとき、メッセージの受け渡しを開始する必要があることに気付きましたコンポーネントとコンポーネントの更新の実行の順序付け...
それで、私は戻ってT-machinesブログを読みました。コメントスレッドには多くの情報が含まれており、それらの中で、コンポーネントには動作がないことを強調しており、動作はエンティティシステムによって提供されます。このように、コンポーネント間のメッセージを渡したり、コンポーネントの更新を注文したりする必要はありません。これは、システム実行のグローバルな順序によって注文が決定されるためです。OK。多分それはあまりにも抽象的です。
とにかく、イテレーション2の場合、これはブログから収集したものです。
EntityManager-コンポーネントの「データベース」として機能し、特定のタイプのコンポーネントを含むエンティティを照会できます。これは、インメモリデータベースによってバックアップすることもでき、高速アクセスが可能です。詳細については、t-machine part 5を参照してください。
EntitySystem-各システムは本質的に、一連のエンティティで動作する単なるメソッドです。各システムは、エンティティのコンポーネントx、y、zを使用して、作業を完了させます。したがって、コンポーネントx、y、zのエンティティーについてマネージャーにクエリを実行し、その結果をシステムに渡します。
エンティティ-longのような単なるID。エンティティは、一連のコンポーネントインスタンスを「エンティティ」にグループ化するものです。
コンポーネント-一連のフィールド....動作なし!ビヘイビアーを追加し始めると、単純なSpace Invadorsゲームでも面倒になり始めます。
編集:ちなみに、 'dt'は最後のメインループ呼び出しからのデルタ時間です
だから私のメインのInvadorsループはこれです:
Collection<Entity> entitiesWithGuns = manager.getEntitiesWith(Gun.class);
Collection<Entity> entitiesWithDamagable =
manager.getEntitiesWith(BulletDamagable.class);
Collection<Entity> entitiesWithInvadorDamagable = manager.getEntitiesWith(InvadorDamagable.class);
keyboardShipControllerSystem.update(entitiesWithGuns, dt);
touchInputSystem.update(entitiesWithGuns, dt);
Collection<Entity> entitiesWithInvadorMovement = manager.getEntitiesWith(InvadorMovement.class);
invadorMovementSystem.update(entitiesWithInvadorMovement);
Collection<Entity> entitiesWithVelocity = manager.getEntitiesWith(Velocity.class);
movementSystem.move(entitiesWithVelocity, dt);
gunSystem.update(entitiesWithGuns, System.currentTimeMillis());
Collection<Entity> entitiesWithPositionAndForm = manager.getEntitiesWith(Position.class, Form.class);
collisionSystem.checkCollisions(entitiesWithPositionAndForm);
最初は少し奇妙に見えますが、非常に柔軟です。最適化も非常に簡単です。コンポーネントタイプが異なると、異なるバッキングデータストアを使用して、検索を高速化できます。「フォーム」クラスの場合は、衝突検出のアクセスを高速化するために、それをクワッドツリーでサポートすることができます。
私はあなたのようです。私はベテランの開発者ですが、ゲームを書いた経験がありません。私はいくつかの時間をかけて与えられた開発パターンを調査しましたが、これは私の目に留まりました。それは決して物事を行う唯一の方法ではありませんが、非常に直感的で堅牢であることがわかりました。このパターンは、シリーズ「ゲームプログラミングジェム」の第6巻-http : //www.amazon.com/Game-Programming-Gems/dp/1584500492で正式に議論されたと思います。私は自分で本を読んだことはありませんが、ゲームプログラミングの事実上のリファレンスであると聞いています。