Suponha que você tenha uma cena composta por um mundo , um jogador e um chefe. Ah, e este é um jogo de terceira pessoa, então você também tem uma câmera .
Portanto, sua cena fica assim:
class Scene {
World* world
Player* player
Enemy* boss
Camera* camera
}
(Pelo menos, esses são os dados básicos . Como você os contém, é com você.)
Você só deseja atualizar e renderizar a cena quando estiver jogando, não quando estiver em pausa ou no menu principal ... para anexá-la ao estado do jogo!
State* gameState = new State();
gameState->addScene(scene);
Agora o seu estado do jogo tem uma cena. Em seguida, você deseja executar a lógica na cena e renderizar a cena. Para a lógica, você acabou de executar uma função de atualização.
State::update(double delta) {
scene->update(delta);
}
Dessa forma, você pode manter toda a lógica do jogo na Scene
classe. E apenas por uma questão de referência, um sistema de componentes de entidade pode fazê-lo assim:
State::update(double delta) {
physicsSystem->applyPhysics(scene);
}
De qualquer forma, agora você conseguiu atualizar sua cena. Agora você deseja exibi-lo! Para o qual fazemos algo semelhante ao acima:
State::render() {
renderSystem->render(scene);
}
Ai está. O renderSystem lê as informações da cena e exibe a imagem apropriada. Simplificado, o método para renderizar a cena pode ser assim:
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());
}
Realmente simplificado, você ainda precisará, por exemplo, aplicar uma rotação e tradução com base em onde seu jogador está e onde ele está. (Meu exemplo é um jogo em 3D, se você for em 2D, será um passeio no parque).
Espero que isto seja o que você estava procurando? Como você pode se lembrar do exposto acima, o sistema de renderização não se importa com a lógica do jogo . Ele usa apenas o estado atual da cena para renderizar, ou seja, extrai as informações necessárias para renderizar. E a lógica do jogo? Não se importa com o que o renderizador faz. Caramba, não importa se é exibido!
E você também não precisa anexar informações de renderização à cena. Deve ser suficiente que o renderizador saiba que precisa renderizar um orc. Você já carregou um modelo orc, que o renderizador sabe exibir.
Isso deve satisfazer seus requisitos. A representação gráfica e a lógica são acopladas , porque ambas usam os mesmos dados. No entanto, eles são separados , porque nenhum deles depende do outro!
EDIT: E apenas para responder por que alguém faria assim? Porque é mais fácil é a razão mais simples. Você não precisa pensar em "tal e tal aconteceu, agora devo atualizar os gráficos". Em vez disso, você faz as coisas acontecerem, e cada quadro do jogo examina o que está acontecendo no momento e o interpreta de alguma forma, fornecendo um resultado na tela.