3

ゲーム オブジェクトの機能から物理シミュレーションを分離するゲーム エンジンがあります。だから私は物理的な体のための純粋な仮想クラスを持っています

class Body

そこから、物理シミュレーションのさまざまな実装を導き出します。私のゲームオブジェクトクラスは次のようになります

class GameObject {
public:
   // ...
private:
   Body *m_pBody;
};

その特定のゲームに必要な実装をプラグインできます。しかし、私がBody持っているのはGameObject. だから私は自分が次のようなものをたくさん書いていることに気づきました

Vector GameObject::GetPosition() const { return m_pBody->GetPosition(); }

私はそれらすべてをスクラッチして、次のようなことをしたくなります

pObject->GetBody()->GetPosition();

しかし、これは間違っているようです (つまり、デメテルの法則に違反しています)。さらに、実装から使用法に冗長性をプッシュするだけです。だから私はこれを行う別の方法を探しています。

4

4 に答える 4

3

1 つのアプローチとして、Bodyインターフェイスを複数のインターフェイスに分割し、それぞれに異なる目的を持たGameObjectせ、公開する必要のあるインターフェイスのみの所有権を与えることができます。

class Positionable;
class Movable;
class Collidable;
//etc.

具体的なBody実装はおそらくすべてのインターフェースを実装しますが、GameObjectその位置を公開するだけでよい は (依存性注入を通じて)Positionableインターフェースを参照するだけです:

class BodyA : public Positionable, Movable, Collidable {
    // ...
};

class GameObjectA {
private:
    Positionable *m_p;
public:
    GameObjectA(Positionable *p) { m_p = p; }
    Positionable *getPosition() { return m_p; }
};

BodyA bodyA;
GameObjectA objA(&bodyA);

objA->getPosition()->getX();
于 2009-01-22T05:11:48.583 に答える
1

ゲーム階層には、多くの継承が含まれるべきではありません。私はあなたにどのウェブページも指摘することはできませんが、それは私がいくつかの情報源、特にゲームの宝石シリーズから集めた感覚です。

ship-> tie_fighter、ship->x_wingのような階層を持つことができます。ただし、PlaysSound->tie_fighterではありません。tie_fighterクラスは、それ自体を表すために必要なオブジェクトで構成されている必要があります。物理学の部分、グラフィックスの部分など。ゲームオブジェクトと対話するための最小限のインターフェイスを提供する必要があります。エンジンまたは物理ピースにできるだけ多くの物理ロジックを実装します。

このアプローチでは、ゲームオブジェクトはより基本的なゲームコンポーネントのコレクションになります。

とはいえ、ゲームイベント中にゲームオブジェクトの物理的な状態を設定できるようにする必要があります。したがって、さまざまな状態を設定するために説明した問題が発生します。それはただ厄介ですが、それは私がこれまでに見つけた最良の解決策です。

私は最近、Box2Dのアイデアを使用して、より高いレベルの状態関数を作成しようとしました。位置などを設定するための関数SetXFormがあります。速度と角速度のためのSetDXForm用の関数がもう1つあります。これらの関数は、物理状態のさまざまな部分を表すパラメーターとしてプロキシオブジェクトを取ります。このようなメソッドを使用すると、状態を設定する必要のあるメソッドの数を減らすことができますが、最終的には、より細かいメソッドを実装することになり、プロキシオブジェクトは、スキップして節約するよりも多くの作業が必要になります。いくつかの方法で。

だから、私はそれほど助けませんでした。これは前の答えに対する反論でした。

要約すると、私はあなたが多くの方法のアプローチに固執することをお勧めします。ゲームオブジェクトと物理オブジェクトの間には、必ずしも単純な1対1の関係があるとは限りません。1つのゲームオブジェクトで爆発からのすべてのパーティクルを表す方がはるかに簡単であることに遭遇しました。ボディポインタをあきらめて公開しただけでは、問題を単純化することはできなかったでしょう。

于 2009-01-22T06:08:06.410 に答える
0

ゲームの表現から何かの物理学を分離していることを正しく理解していますか?

つまり、次のようなものが表示されますか?

class CompanionCube
{
    private:
        Body* m_pPhysicsBody;
};

?

もしそうなら、それは私には悪いにおいがします。技術的には、「GameObject」物理オブジェクトであるため、Body から派生する必要があります。

物理モデルを交換することを計画しているようで、それが集約を介してそれを行おうとしている理由です。その場合は、「実行時に物理タイプを交換する予定ですか、それともコンパイル時に行う予定ですか?」 ?」。

コンパイル時間が答えなら、Body からゲーム オブジェクトを派生させ、Body をデフォルトにしたい物理ボディの typedef にします。

ランタイムの場合は、内部でその切り替えを行う「ボディ」クラスを作成する必要があります。これは、異なる物理をいじることが目的である場合、悪い考えではないかもしれません。

または、ゲーム オブジェクトのタイプ (水、剛体など) に応じて Body の「親」クラスが異なる場合があるため、派生でそれを明示することができます。

とにかく、この回答は多くの推測に基づいているため、とりとめのないことをやめます。;) 基地から外れている場合はお知らせください。回答を削除します。

于 2009-01-22T06:53:14.243 に答える