1

私が書いているプログラムの動物のようなエンティティで満たされた C++ の 2 次元の世界があります。私はワールドクラスとエンティティクラス(およびエンティティから継承するさまざまな種類のエンティティのカスケード)を持っています。

エンティティがどの世界にあるかを「認識」し、エンティティの2次元配列とうまくやり取りできるようにしたいのですが、世界から継承したくありません(結局のところ、エンティティ世界ではありません)。そのため、これを実装するための良い方法についていくつかのアイデアを得ようとしています。もちろん、各エンティティにそれが存在する世界へのポインタを含めることもできますが、かなり面倒です。2次元配列のエンティティがどのワールドオブジェクトに含まれているかを「知る」簡単な方法はありますか?

別のオブジェクトのメンバー変数であるオブジェクトが、それを含むオブジェクトを知る方法はc ++にありますか?

ありがとう!

4

4 に答える 4

3

集計 (各エンティティにワールド ポインターを提供する) は、最も単純なソリューションです。もう 1 つの解決策は、世界とエンティティへのポインターを保持し、それらの関係を格納し、それらの間の通信 (名前の由来) を仲介する 3 番目のメディエーター オブジェクトを用意することです。このオブジェクトはグローバル シングルトンである可能性があります (ほとんどのプログラマーは身震いするでしょうが、これらのいくつかは悪いことではないと思います)、そうでなければ、すべてのワールドとエンティティは通信するためにそれへのポインターを必要としますが、これは明らかに大きなものではありません。最初のソリューションの改善。

于 2013-05-15T16:16:21.660 に答える
1

私は世界クラスを持っています

まあ。


それはさておき、あなたの実体とその環境との有意義な相互作用は何ですか? 任意の情報を照会したり、地平線を見渡したり、他のエンティティの状態を調べたりできる必要がありますか?

それとも、その場所と属性に基づいて、ビューが制限されているはずですか?

最初のケースでは、明らかに神のような存在であり、カプセル化や懸念の分離などのありふれた懸念は適用されません。

2 番目のケースでは、インタフェースを公開して (カップリングを減らすために抽象化できます)、必要なものだけを表示できるようにします。


OK、2番目のケースは次のようになります

class World; // is a dumb container of entities
class Environment; // is an entity's window on the world
class Entity {
public:
    void take_a_turn(Environment&) = 0;
};
class Environment {
public: // control what an entity can do to (see of) the World
    container<const Entity*> visible_entities() const;
    result attempt_to_eat(const Entity*);
    result attempt_to_mate(const Entity*);
    result run_away_from(const Entity*);
};

もちろん、エンティティ オブジェクトがアクティブな場合(つまり、独自のスレッドで自律的かつ継続的に実行される場合)、ワールドまたは環境への参照またはポインタを保持する必要があります。

ただし、一度に 1 つずつ呼び出しているだけの場合は、何かを実行する機会があれば、そのたびに参照を渡しても問題ありません。

于 2013-05-15T16:14:11.547 に答える
1

私があなたを正しく理解していると仮定すると、各エンティティのワールド ポインターに代わる方法は、各ワールドに一意の ID を与え、エンティティがワールドに追加されるときにその ID をエンティティに格納することです。

于 2013-05-15T16:15:22.947 に答える
0

世界のために、ある種のグローバルエンジンを作成できるかもしれません。エンジンにはシステムがあり、世界はエンジン内のシステムと見なすことができます。エンティティのコンストラクターでエンジンからワールド システムを要求し、そこで必要なことを行います。

class World : public System
{
  // info in here
}


class Engine 
{
  public:
    World * getWorldSystem(); // Not as good
    System * getSystem( std::string name ); // uses lookup, convert to right type

}

エンジンクラスの問題は「どうやって参照するの?」ほとんどの場合、エンジンの .h ファイルを含めます。

extern Engine * ENGINE;

その内部は恐ろしいことだと理解していますが、エンジン/システムアーキテクチャでは、どこかにそれを持たなければなりません. または、シングルトンを明示的に使用します。

継承ツリーに関しては、設計スキームを完全に変更する可能性があります。コンポーネント ベースのアーキテクチャは、この問題を解決する方法となる可能性があります。

継承は多くの状況で理にかなっていますが、コンポーネント ベースのエンティティを構築すると、各動物が持つ必要のある奇妙な型の巨大な連鎖を処理するのに役立ちます。

取った:

class Component
{
  public:
    Component();
    virtual ~Component();

}

class WalkComponent : public Component
{
  public:
    Walk(); // Something here allows the entity to walk on the ground
}

class FlightComponent : public Component
{
  public:
    Fly(); // Something in here moves the entity around using flight
}

両方を許可する継承ツリーを作成しようとするのではなく、walk コンポーネントと flight コンポーネントをエンティティにアタッチすると、両方を持つことがすぐにわかります。

于 2013-05-15T16:21:36.797 に答える