ワールド、プレイヤー、ボスで構成されるシーンがあるとします。ああ、これは3人称ゲームなので、カメラも持っています。
したがって、シーンは次のようになります。
class Scene {
World* world
Player* player
Enemy* boss
Camera* camera
}
(少なくとも、それは基本的なデータです。データをどのように含めるかはあなた次第です。)
シーンを更新してレンダリングするのは、ゲームをプレイしているときだけであり、一時停止しているときやメインメニューではないので、ゲームの状態にアタッチします。
State* gameState = new State();
gameState->addScene(scene);
これで、ゲームの状態にシーンがあります。次に、シーンでロジックを実行して、シーンをレンダリングします。ロジックについては、更新関数を実行するだけです。
State::update(double delta) {
scene->update(delta);
}
このようにして、すべてのゲームロジックをScene
クラスに保持できます。参考までに、エンティティコンポーネントシステムでは、次のようにすることもできます。
State::update(double delta) {
physicsSystem->applyPhysics(scene);
}
とにかく、これでシーンを更新することができました。それを表示したい!上記と同様の処理を行います。
State::render() {
renderSystem->render(scene);
}
どうぞ。renderSystemはシーンから情報を読み取り、適切な画像を表示します。簡略化すると、シーンのレンダリング方法は次のようになります。
RenderSystem::renderScene(Scene* scene) {
Camera* camera = scene->camera;
lookAt(camera); // Set up the appropriate viewing matrices based on
// the camera location and direction
renderHeightmap(scene->getWorld()->getHeightMap()); // Just as an example, you might
// use a height map as your world
// representation.
renderModel(scene->getPlayer()->getType()); // getType() will return, for example "orc"
// or "human"
renderModel(scene->getBoss()->getType());
}
本当に単純化されているため、たとえば、プレーヤーの位置とプレーヤーが見ている位置に基づいて回転と移動を適用する必要があります。(私の例は3Dゲームです。2Dで行くと、公園の散歩になります)。
これがあなたが探していたものであることを願っていますか?うまくいけば上から思い出せますが、レンダーシステムはゲームのロジックを気にしません。レンダリングにはシーンの現在の状態のみが使用されます。つまり、レンダリングに必要な情報がシーンから取得されます。そして、ゲームロジック?レンダラーが何をするかは関係ありません。表示されても問題ありません。
また、レンダリング情報をシーンに添付する必要もありません。それは、レンダラーがオークをレンダリングする必要があることを知っているだけで十分です。orcモデルはすでにロードされているため、レンダラーはこれを表示することができます。
これは要件を満たすはずです。グラフィック表現とロジックは両方とも同じデータを使用するため、結合されています。しかし、どちらも他に依存していないため、それらは別々です。
編集:そしてなぜこれがなぜこのようにするのかを答えるには?一番簡単な理由は簡単だからです。「こういうことが起こったので、グラフィックを更新する必要がある」と考える必要はありません。代わりに、物事を発生させ、フレームごとに、ゲームが現在起こっていることを確認し、何らかの方法で解釈して、画面上の結果を提供します。