2Dゲームのオブジェクトはそれ自体をレンダリングする必要がありますか?


16

私はタイルベースではない2Dストリートファイターのようなゲームを作っています。通常、人々はエンティティをレンダリングするレンダラーに与えることを推奨しますが、それ自体をレンダリングするのではなく、逆の方が良いようです、

なぜ一方が他方より優れているのですか?

ありがとう


なぜ逆が良いと思いますか?

1
@Martinは、オブジェクトがどのビットマップを使用するかを示唆するため、なぜobject-> render();
jmasterx

回答:


11

いくつかの考慮事項:

  • あなたが言及したように、各スプライトはどのビットマップを使用するかを「ヒント」しなければなりませんが、エンティティがそれ自体をレンダリングする必要がある場合。その「ヒント」は何でしょうか?各スプライトの異なるビットマップ、スプライトシートなどへの参照である場合、必要以上のメモリを使用したり、そのメモリの管理に問題が発生したりする可能性があります。独立したレンダラーの利点は、アセット管理を担当するクラスが1つだけであることです。とはいえ、SF2のような格闘ゲームでは、スプライトは2つしかありません;)

  • 他の場所で述べたように、グラフィカルAPIを変更する場合は、すべてのスプライトのコードを変更する必要があります。

  • グラフィカルなコンテキストへの参照なしでレンダリングが行われることはほとんどありません。そのため、この概念を表すグローバル変数があるか、各スプライトにrender(GraphicalContext ctx)とのインターフェースがあります。これにより、グラフィカルAPIとゲームのロジック(一部の人は違法と感じる人もいます)が混在し、コンパイルの問題が発生する可能性があります。

  • レンダリングを個々のエンティティから分離することは、必ずしもグラフィックをまったく必要としないシステムとしてゲームを表示するための興味深い第一歩であると個人的に感じています。つまり、レンダリングを邪魔にしないと、エンティティの座標、内部状態などが重要な「非グラフィック世界」で多くのゲームプレイが発生することに気付くということです。これにより、自動テスト、より分離されたシステムなどへの扉が開かれます...

全体として、レンダリングは別のクラスによって行われるシステムを好む傾向があります。だからといって、レンダラーを記述しやすくしたり効率的にしたりする場合、スプライトに「グラフィック的に関連する」属性(アニメーション名、アニメーションフレーム、高さx幅、スプライトIDなど)を持たないというわけではありません。

そして、それが3Dに適用されるかどうかはわかりません(メッシュの概念と使用する座標変数はおそらく3D APIに関連付けられますが、x、y、h、wは2Dにほとんど依存しませんAPI)。

これが役に立てば幸いです。


11

レンダリングシステムは、いつ描画されるかを制御する必要があります。代わりにスプライトがレンダリングを制御している場合、多くの効率の向上と柔軟性を失います。レンダリングシステムを制御すると、コードがよりきれいになると思います。

集中レンダリングのいくつかの利点:

  • z-ordering:
    ゲームオブジェクト自体がレンダリングを担当する場合、正しい順序で呼び出す必要があります。そうしないと、背景オブジェクトが前景オブジェクトの上に描画される場合があります。
    レンダーシステムを制御すると、すべてのレンダーオブジェクトを並べ替えたり、レンダー時にオーバーラップを検出してそれらをレンダーしたり、すべての順序を無視したりできます。重要なのは、今すぐに決断を下せるということです。
  • バッチ処理:
    レンダリングシステムを制御できるようにすることのもう1つの明らかな利点は、バッチ処理です。ここでも、レンダーシステムは共有のテクスチャをスプライトレンダーでバッチ処理するオプションが必要です。三角形のスライスを使用し、1回の呼び出しですべてをレンダリングできます。一部のレンダリング計算をキャッシュできる場合があります。または、各スプライトをそのような派手なものなしで順番にレンダリングすることもできます。(注:各オブジェクトがそれ自体をレンダリングするときにバッチ処理が可能ですが、問題は効率が悪く複雑です。)

これをゲームに実装して、ゲームオブジェクトにレンダーシステムで描画するスプライトを登録させる方法。オブジェクトがオブジェクトを描画したくない場合、スプライトの登録を解除するか、非アクティブとしてマークします。

言ったことすべて。ゲームオブジェクトを自分でレンダリングする方が簡単な場合は、必ずそのようにします。完璧なアーキテクチャを構築することよりも、進歩を遂げて何か/何かを描くことが非常に重要です。


オブジェクトが自分自身を描画する場合のz-orderingについて、システムは描画メソッドを呼び出す順序を決定できませんか?つまり、集中型と非集中型は、zオーダーに関して違いがないようです。
GorillaApe

3

免責事項:あなたの質問はあまり詳細ではないので、一般的な原則で回答しています。私があなたの使用または「レンダリング」を誤解した場合は、すみません。

私は通常、外部オブジェクトを使用して、シーン内のさまざまなアクターを、個々の「アクターオブジェクト」の外部のシーンレベルのプロパティとメソッドをカプセル化する方法としてレンダリングします。シーン内のオブジェクトには、内部メソッドとプロパティのみを含める必要があります。彼らは自分自身が何であり、何をしているのかを知っているだけです。おそらく、それらはゲーム内の他のオブジェクトやユーザー入力の影響を受けます。これは、画面上でのレンダリング方法/レンダリングに影響します。たとえば、「directorオブジェクト」は、「w」キーを押してジャンプしてから、アクターオブジェクトに.jump()を伝えることができます。このような監督レベルのロジックは、シーンに完全に出入りするよう俳優に指示することもできます。

乾杯、デビッド


しかしその意味では、監督は単にacton-> setVisible(false)と言うことはできません。?
jmasterx

setVisible(false)の場合でも、アクタの可視変数をチェックしてtrueの場合にのみレンダリングすることによりレンダリングを行うのは外部エンティティです。
ナビゲーション

アクターを非表示にするだけでは、シーンから削除されません。また、衝突などへの参加を停止する必要があります。
finnw

3

いつかゲームを別の解像度(iPhoneや友達など)に移植したい場合はどうでしょう。したがって、レンダリングの変更に関するグローバルプロパティは、どのようにコードを簡単に更新できますか?


3

私が使用したのは、オブザーバーベースのデザインです。レンダリングしたいクラスのインスタンスを作成すると、それへのポインターが中央のRendererクラスに保存されました。を呼び出すRenderFrame()と、レンダラーにはレンダリングに必要なすべての既存オブジェクトが既にあり、そのためにプロパティにアクセスします。クラス自体は、それらがレンダリングされることをまったく知りませんでした。このAPIは素晴らしく、クリーンで使いやすいものでした。


1
+1興味深い。グラフィックに訪問者パターンを使用しながら、私はサウンドにこのアプローチを使用しました。グラフィックとAIが同じクロックで実行されている間、オーディオミキサーが別のクロックで実行されているため、イベントモデルが簡単になるため、これはサウンドにとってより意味があると思いました。また、(オーディオチャネルのパン/リバーブを変更する)移動イベントが数ミリ秒遅れて到着する場合は重要ではありませんが、スプライトが間違った状態で描画される場合は重要です。
finnw

2

一般に、コードの保守と拡張がどれほど簡単かが常に重要です。明日は、現在使用しているグラフィックス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();
}

またはそれに近い、私はそれがまったく問題だとは思わない。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.