私が作成している 2D ゲーム (Android 用) では、GameObject が複数の GameComponent オブジェクトを保持するコンポーネント ベースのシステムを使用しています。GameComponents には、入力コンポーネント、レンダリング コンポーネント、弾丸放出コンポーネントなどがあります。現在、GameComponents はそれらを所有し、それを変更できるオブジェクトへの参照を持っていますが、GameObject 自体はコンポーネントのリストを持っているだけで、オブジェクトが更新されたときに更新できる限り、コンポーネントが何であるかは気にしません。
コンポーネントには、GameObject が知る必要のある情報が含まれている場合があります。たとえば、衝突検出の場合、GameObject はそれ自体を衝突検出サブシステムに登録して、別のオブジェクトと衝突したときに通知を受けます。衝突検出サブシステムは、オブジェクトのバウンディング ボックスを認識する必要があります。x と y をオブジェクトに直接格納します (複数のコンポーネントで使用されるため) が、幅と高さは、オブジェクトのビットマップを保持するレンダリング コンポーネントにしかわかりません。その情報を取得するメソッド getBoundingBox または getWidth を GameObject に入れたいと思います。または、一般的に、コンポーネントからオブジェクトに情報を送信したいと考えています。しかし、私の現在の設計では、GameObject はリストにある特定のコンポーネントを認識していません。
この問題を解決するには、いくつかの方法が考えられます。
コンポーネントの完全に一般的なリストを用意する代わりに、GameObject にいくつかの重要なコンポーネント用の特定のフィールドを持たせることができます。たとえば、renderingComponent というメンバー変数を持つことができます。使用するオブジェクトの幅を取得する必要があるときはいつでも
renderingComponent.getWidth()
。このソリューションでは、コンポーネントの一般的なリストを引き続き使用できますが、一部のコンポーネントの扱いが異なります。より多くのコンポーネントを照会する必要があるため、いくつかの例外的なフィールドが発生することになるのではないかと心配しています。一部のオブジェクトには、レンダリング コンポーネントさえありません。必要な情報を GameObject のメンバーとして保持しますが、コンポーネントがそれを更新できるようにします。したがって、オブジェクトの幅と高さはデフォルトで 0 または -1 ですが、レンダリング コンポーネントは更新ループでそれらを正しい値に設定できます。これはハックのように感じられ、すべてのオブジェクトがそれらを必要としない場合でも、利便性のために多くのものを GameObject クラスにプッシュすることになる可能性があります。
照会できる情報の種類を示すインターフェースをコンポーネントに実装させます。たとえば、レンダリング コンポーネントは、getWidth や getHeight などのメソッドを含む HasSize インターフェイスを実装します。GameObject が幅を必要とする場合、そのコンポーネントをループして HasSize インターフェイスを実装しているかどうかを確認します ( Java またはC# で
instanceof
キーワードを使用)。is
これはより一般的な解決策のように思えますが、欠点の 1 つは、コンポーネントの検索に時間がかかる場合があることです (ただし、ほとんどのオブジェクトには 3 つまたは 4 つのコンポーネントしかありません)。
この質問は特定の問題に関するものではありません。それは私のデザインで頻繁に出てきて、それを処理する最善の方法は何だろうと考えていました。これはゲームであるため、パフォーマンスは多少重要ですが、オブジェクトあたりのコンポーネントの数は一般的に少なくなります (最大 8)。
ショートバージョン
ゲームのコンポーネント ベースのシステムで、一般的なデザインを維持しながら、コンポーネントからオブジェクトに情報を渡す最良の方法は何ですか?