回答:
いくつかの考慮事項:
あなたが言及したように、各スプライトはどのビットマップを使用するかを「ヒント」しなければなりませんが、エンティティがそれ自体をレンダリングする必要がある場合。その「ヒント」は何でしょうか?各スプライトの異なるビットマップ、スプライトシートなどへの参照である場合、必要以上のメモリを使用したり、そのメモリの管理に問題が発生したりする可能性があります。独立したレンダラーの利点は、アセット管理を担当するクラスが1つだけであることです。とはいえ、SF2のような格闘ゲームでは、スプライトは2つしかありません;)
他の場所で述べたように、グラフィカルAPIを変更する場合は、すべてのスプライトのコードを変更する必要があります。
グラフィカルなコンテキストへの参照なしでレンダリングが行われることはほとんどありません。そのため、この概念を表すグローバル変数があるか、各スプライトにrender(GraphicalContext ctx)とのインターフェースがあります。これにより、グラフィカルAPIとゲームのロジック(一部の人は違法と感じる人もいます)が混在し、コンパイルの問題が発生する可能性があります。
レンダリングを個々のエンティティから分離することは、必ずしもグラフィックをまったく必要としないシステムとしてゲームを表示するための興味深い第一歩であると個人的に感じています。つまり、レンダリングを邪魔にしないと、エンティティの座標、内部状態などが重要な「非グラフィック世界」で多くのゲームプレイが発生することに気付くということです。これにより、自動テスト、より分離されたシステムなどへの扉が開かれます...
全体として、レンダリングは別のクラスによって行われるシステムを好む傾向があります。だからといって、レンダラーを記述しやすくしたり効率的にしたりする場合、スプライトに「グラフィック的に関連する」属性(アニメーション名、アニメーションフレーム、高さx幅、スプライトIDなど)を持たないというわけではありません。
そして、それが3Dに適用されるかどうかはわかりません(メッシュの概念と使用する座標変数はおそらく3D APIに関連付けられますが、x、y、h、wは2Dにほとんど依存しませんAPI)。
これが役に立てば幸いです。
レンダリングシステムは、いつ描画されるかを制御する必要があります。代わりにスプライトがレンダリングを制御している場合、多くの効率の向上と柔軟性を失います。レンダリングシステムを制御すると、コードがよりきれいになると思います。
集中レンダリングのいくつかの利点:
これをゲームに実装して、ゲームオブジェクトにレンダーシステムで描画するスプライトを登録させる方法。オブジェクトがオブジェクトを描画したくない場合、スプライトの登録を解除するか、非アクティブとしてマークします。
言ったことすべて。ゲームオブジェクトを自分でレンダリングする方が簡単な場合は、必ずそのようにします。完璧なアーキテクチャを構築することよりも、進歩を遂げて何か/何かを描くことが非常に重要です。
免責事項:あなたの質問はあまり詳細ではないので、一般的な原則で回答しています。私があなたの使用または「レンダリング」を誤解した場合は、すみません。
私は通常、外部オブジェクトを使用して、シーン内のさまざまなアクターを、個々の「アクターオブジェクト」の外部のシーンレベルのプロパティとメソッドをカプセル化する方法としてレンダリングします。シーン内のオブジェクトには、内部メソッドとプロパティのみを含める必要があります。彼らは自分自身が何であり、何をしているのかを知っているだけです。おそらく、それらはゲーム内の他のオブジェクトやユーザー入力の影響を受けます。これは、画面上でのレンダリング方法/レンダリングに影響します。たとえば、「directorオブジェクト」は、「w」キーを押してジャンプしてから、アクターオブジェクトに.jump()を伝えることができます。このような監督レベルのロジックは、シーンに完全に出入りするよう俳優に指示することもできます。
乾杯、デビッド
いつかゲームを別の解像度(iPhoneや友達など)に移植したい場合はどうでしょう。したがって、レンダリングの変更に関するグローバルプロパティは、どのようにコードを簡単に更新できますか?
私が使用したのは、オブザーバーベースのデザインです。レンダリングしたいクラスのインスタンスを作成すると、それへのポインターが中央のRendererクラスに保存されました。を呼び出すRenderFrame()
と、レンダラーにはレンダリングに必要なすべての既存オブジェクトが既にあり、そのためにプロパティにアクセスします。クラス自体は、それらがレンダリングされることをまったく知りませんでした。このAPIは素晴らしく、クリーンで使いやすいものでした。
一般に、コードの保守と拡張がどれほど簡単かが常に重要です。明日は、現在使用しているグラフィックスAPIが気に入らず、切り替えたいことを理解します。すべてのオブジェクトクラスを調べてすべてを変更する必要がありますか、それともプロジェクトの1つの中心点でコードを変更するだけですか?
render()を呼び出すときにオブジェクトが実際に何をしているかによって異なります。グラフィックエンジンの周りでメソッド呼び出しをラップしている限り、ロジック<->グラフィックの区別が引き続き与えられるため、それは完全に問題ありません。
たとえば、render()メソッドが基本的に便利なメソッドであり、次のように見える場合:
void MyClass::render(const Graphics &g)
{
g.draw(this);
}
または
void MyClass::render()
{
mySprite->render();
}
または
void MyClass::render()
{
mySprite->UseShader(thatshader);
mySprite->render();
}
またはそれに近い、私はそれがまったく問題だとは思わない。