2017-01-22 18 views
0

私はC++でゲームエンジンを設計している。私は現在、ゲーム内のさまざまなエンティティを分類することに取り組んでいます。私の基本クラスは、MovableObjectとFixedObjectの2つのクラスが継承するSpriteObjectです。今私は、例えばMovableObjectのインスタンスを作成して、スプライトのベクトルとMovableObjectのベクトル私はちょうど行うには、それを追加したい場合: そのオブジェクトのベクトルにオブジェクトを自動的に追加する。

Vector<Sprite*> sprites; 
Vector<MovableObject*> movableObjects; 
MovableObject* movingObject = new MovableObject(); 
sprites.push_back(movingObject); 
movableObjects.push_back(movingObject); 

しかし、異なるカテゴリとエンティティが育つように、コードが大きいでしょう

(そしてそれが属しているすべてのベクトルにすべてのエンティティを追加するのは面倒です)。どのように私は自動的にそれが作成時に属するベクトルにオブジェクトを追加するのですか?

EDIT 1:私はちょうどソリューションを思いついたと思います。もし私がシーン内のエンティティのすべてのベクトルを保持するグローバル静的クラスEntitiesを作るなら、どうでしょうか?すべてのエンティティはこのクラスにアクセスできます。エンティティが作成されると、そのグローバルクラスの対応するベクトルにポインタバージョンのオブジェクトを追加するだけです。

編集2:私の解決策では、手動ですべてのエンティティを一致するベクターに手動で追加する必要があることを忘れていました。私はちょうど異なるエンティティの間で仕事を分割しました。

+0

「スプライト」に追加するだけで、一部のメンバ変数をクエリすることによって 'MoveableObject'であることが分かります。 –

+2

これらのリストにアクセスする手段があります(たとえば、各コンポーネントにはすべてのインスタンスの静的ベクトルがあります)。特定のコンポーネントのコンストラクタで適切なリストにサインアップします。しかし、私はそのアプローチをお勧めしません。むしろ、コンポーネントの追跡/登録を必要とするすべての必要なロジックを実行するファクトリを使用してください。 –

+0

代わりに仮想関数と多相を使用してみませんか?次に、オブジェクトのコレクションが1つだけ必要です。 –

答えて

2

これは良い問題です。

SpriteクラスにaddToVector()メソッドがあり、各派生クラスがそれをオーバーライドして対応するベクターに追加されます。

+0

ありがとう!これは完全に私の問題を解決しました:) – Bonbin

+1

シンプルで素敵な解決策、私はちょうどコメントを追加します。それらの派生クラスのコンストラクタでaddToVector()の呼び出しを追加することが魅力的かもしれませんが、コンストラクタで仮想関数を呼び出すことは厳密には安全ではなく、未定義の動作につながる可能性があります。オブジェクトを作成してインスタンス上でaddToVectorを呼び出す専用のファクトリ関数を用意することは、ユーザーがそうすることを忘れないように、良い解決策のように思えます。 –

1

私は別のアプローチを提案します。しかし私が始める前に、私はあなたの現在のデザインで一つのことを書きたいと思います。

ファサードの背後にあるオブジェクトの作成を非表示にします。それをシーンなどと呼んでください。 newを手動で使用することは、いくつかの観点から悪いことです。まず、オブジェクトの割り当て/構築方法についてスキームを変更したい場合は、コード内のどこでも変更する必要があります。 Sceneのようなファクトリを持っている場合は、実装を変更するだけで、scene->CreateObject<Sprite>()の呼び出しは他のどこでも同じままになります。カスタムメモリー割り当てスキームやオブジェクトプールなどの追加を開始したら、これは重要になるかもしれません。そして、あなたがエンジンを増やし始めるのであれば、ある時点であなたはそうなるでしょう。これはちょうどエクササイズと楽しいプロジェクトのためであっても、私たちは皆実際にやったようにこれをしたいと思っています;)

コアに戻る - 濫用の継承をしないでください。

MovableObjectはスプライトではありません。静的オブジェクトはスプライトでもありません。それらは、可動で静的な要素です。

スプライトは、移動または静的である可能性があるため、動的要素または静的要素の動作をします。

代わりに構図を使用してください。スプライトが動作を受け入れるようにするか、動作のリストを改善します。実際には、Sprite自体はGameオブジェクトの動作でもあり、ユーザーに表示される方法を制御します。

ダイナミックなもののような複数の動作にアタッチできるオブジェクトがあれば、それはシーンにスプライトが存在し、さらにエミッタがサウンドになります。

これらのビヘイビアをオブジェクトに追加する場合は、オブジェクトを最初に作成する必要があります。彼らは、作成されたときに、どのリストを購読すべきかを決めることができます。

これは実際によく知られているシステムのためのすべてのメタファであり、うまく動作することが実証されており、今日のほとんどのゲームエンジンで実際に使用されています。そのエンティティコンポーネントシステム。

ビヘイビアは、エンティティであり、コンポーネントはビヘイビアであり、それぞれはコンポーネントを認識し、それらの更新/処理方法を知っている1つのシステムによって制御されます。

シーン内のオブジェクトは、それらに関連付けられた一連のコンポーネントです。

+0

私は実際に、複数のオブジェクトに動作(衝突など)を適用できるテンプレートというものを使用することを計画していました。しかし、私がコメントで述べたように、これは非常に厳密なガイドラインを持つ学校プロジェクトであり、現在のアプローチが維持されるように継承を使用する必要があることを指定しています。私の質問はすでに答えられていますが、非常に有益な投稿のためにあなたに+1を与えてください、そして、私はおそらく、あなたが今後のプロジェクトで決定しているデザインパターンを見ていきます:) – Bonbin

関連する問題