Li recentemente este artigo no Game Loops: http://www.koonsolo.com/news/dewitters-gameloop/
E a última implementação recomendada está me confundindo profundamente. Eu não entendo como isso funciona, e parece uma bagunça completa.
Entendo o princípio: atualize o jogo a uma velocidade constante, com o que restar renderize o jogo quantas vezes for possível.
Presumo que você não pode usar um:
- Obtenha entrada para 25 ticks
- Render jogo para 975 ticks
Abordagem, já que você receberia informações para a primeira parte da segunda e isso pareceria estranho? Ou é isso que está acontecendo no artigo?
Essencialmente:
while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP)
Como isso é válido?
Vamos assumir seus valores.
MAX_FRAMESKIP = 5
Vamos supor next_game_tick, que foi designado momentos após a inicialização, antes que o loop principal do jogo seja ... 500.
Finalmente, como estou usando SDL e OpenGL para o meu jogo, com o OpenGL sendo usado apenas para renderização, vamos assumir que GetTickCount()
retorna o tempo desde que SDL_Init foi chamado, o que ocorre.
SDL_GetTicks -- Get the number of milliseconds since the SDL library initialization.
Fonte: http://www.libsdl.org/docs/html/sdlgetticks.html
O autor também assume isso:
DWORD next_game_tick = GetTickCount();
// GetTickCount() returns the current number of milliseconds
// that have elapsed since the system was started
Se expandirmos a while
declaração, obtemos:
while( ( 750 > 500 ) && ( 0 < 5 ) )
750 porque o tempo passou desde que next_game_tick
foi atribuído. loops
é zero, como você pode ver no artigo.
Então entramos no loop while, vamos fazer alguma lógica e aceitar alguma entrada.
Yadayadayada.
No final do loop while, que eu lembro que você está dentro do loop principal do jogo, é:
next_game_tick += SKIP_TICKS;
loops++;
Vamos atualizar a aparência da próxima iteração do código while
while( ( 1000 > 540 ) && ( 1 < 5 ) )
1000 porque o tempo passou para obter entrada e fazer coisas antes de atingirmos a próxima ineteração do loop, em que GetTickCount () é chamado.
540 porque, no código 1000/25 = 40, portanto, 500 + 40 = 540
1 porque nosso loop iterou uma vez
5 , você sabe o porquê.
Então, como esse loop While é claramente dependente MAX_FRAMESKIP
e não o pretendido, TICKS_PER_SECOND = 25;
como o jogo deve funcionar corretamente?
Não foi surpresa para mim que, quando eu implementei isso no meu código, eu adicionasse corretamente, simplesmente renomeei minhas funções para manipular a entrada do usuário e desenhar o jogo com o que o autor do artigo possui em seu código de exemplo, o jogo não fez nada .
Coloquei um fprintf( stderr, "Test\n" );
loop while que não é impresso até o jogo terminar.
Como esse loop do jogo é executado 25 vezes por segundo, garantido, enquanto é renderizado o mais rápido possível?
Para mim, a menos que esteja faltando algo ENORME, parece ... nada.
E essa estrutura, desse loop while, supostamente funciona 25 vezes por segundo e atualiza o jogo exatamente o que eu mencionei anteriormente no início do artigo?
Se for esse o caso, por que não podemos fazer algo simples como:
while( loops < 25 )
{
getInput();
performLogic();
loops++;
}
drawGame();
E conte para interpolação de alguma outra maneira.
Perdoe minha pergunta extremamente longa, mas este artigo fez mais mal do que bem para mim. Estou severamente confuso agora - e não tenho idéia de como implementar um loop de jogo adequado por causa de todas essas perguntas que surgiram.