Ao criar jogos, você geralmente cria o seguinte objeto de jogo do qual todas as entidades herdam:
public class GameObject{
abstract void Update(...);
abstract void Draw(...);
}
Assim, ao atualizar o loop, você itera sobre todos os objetos do jogo e dá a eles a chance de mudar de estado; depois, no próximo loop, você itera novamente sobre todos os objetos do jogo e dá a eles a chance de se desenhar.
Embora isso funcione razoavelmente bem em um jogo simples com um renderizador de encaminhamento simples, geralmente leva a alguns objetos de jogo gigantescos que precisam armazenar seus modelos, várias texturas e, pior ainda, um método de desenho de gordura que cria um forte acoplamento entre o objeto de jogo, a estratégia de renderização atual e quaisquer classes relacionadas à renderização.
Se eu alterasse a estratégia de renderização de adiada para adiada, precisaria atualizar muitos objetos do jogo. E os objetos do jogo que eu faço não são tão reutilizáveis quanto poderiam ser. É claro que a herança e / ou composição podem me ajudar a combater a duplicação de código e facilitar um pouco a alteração da implementação, mas ainda falta.
Uma maneira melhor, talvez, seria remover completamente o método Draw da classe GameObject e criar uma classe Renderer. O GameObject ainda precisaria conter alguns dados sobre o visual, como qual modelo representá-lo e quais texturas devem ser pintadas no modelo, mas como isso é feito, será deixado para o renderizador. No entanto, muitas vezes há muitos casos de borda na renderização. Embora isso remova o acoplamento rígido do GameObject ao Renderer, o Renderer ainda precisa saber tudo sobre todos os objetos do jogo que o tornariam gordo, todo o conhecimento e fortemente acoplado. Isso violaria algumas boas práticas. Talvez o Design Orientado a Dados possa fazer o truque. Objetos de jogo certamente seriam dados, mas como o renderizador seria movido por isso? Não tenho certeza.
Então, estou perdida e não consigo pensar em uma boa solução. Tentei usar os princípios do MVC e, no passado, tive algumas idéias sobre como usá-lo em jogos, mas recentemente não parece tão aplicável quanto eu pensava. Gostaria muito de saber como todos vocês lidam com esse problema.
De qualquer forma, recapitulando, estou interessado em saber como os seguintes objetivos de design podem ser alcançados.
- Nenhuma lógica de renderização no objeto do jogo
- Acoplamento fraco entre os objetos do jogo e o mecanismo de renderização
- Nenhum processador que conhece tudo
- De preferência alternando o tempo de execução entre os mecanismos de renderização
A configuração ideal do projeto seria uma 'lógica de jogo' separada e renderizaria um projeto de lógica que não precisa se referir um ao outro.
Todo esse pensamento começou quando ouvi John Carmack dizer no twitter que ele tem um sistema tão flexível que ele pode trocar os mecanismos de renderização em tempo de execução e pode até dizer ao sistema para usar os dois renderizadores (um renderizador de software e um renderizador acelerado por hardware) ao mesmo tempo, para que ele possa inspecionar as diferenças. Os sistemas que eu programei até agora não são nem tão flexíveis