Um loop de jogo deve ser baseado em etapas de tempo fixo ou variável? Uma pessoa é sempre superior ou a escolha certa varia de acordo com o jogo?
Etapa de tempo variável
As atualizações de física são passadas para um argumento de "tempo decorrido desde a última atualização" e, portanto, dependem da taxa de quadros. Isso pode significar fazer cálculos como position += distancePerSecond * timeElapsed
.
Prós : suave, mais fácil de codificar
Contras : não determinístico, imprevisível em etapas muito pequenas ou grandes
exemplo deWiTTERS :
while( game_is_running ) {
prev_frame_tick = curr_frame_tick;
curr_frame_tick = GetTickCount();
update( curr_frame_tick - prev_frame_tick );
render();
}
Etapa de tempo fixo
As atualizações podem nem aceitar um "tempo decorrido", pois pressupõem que cada atualização é por um período fixo. Os cálculos podem ser feitos como position += distancePerUpdate
. O exemplo inclui uma interpolação durante a renderização.
Prós : previsível, determinístico (mais fácil de sincronizar na rede?), Código de cálculo mais claro
Contras : não sincronizado para monitorar o v-sync (causa gráficos instáveis a menos que você interpole), taxa de quadros máxima limitada (a menos que você interpole), difícil de trabalhar em estruturas que assuma etapas de tempo variável (como Pyglet ou Flixel )
exemplo deWiTTERS :
while( game_is_running ) {
while( GetTickCount() > next_game_tick ) {
update();
next_game_tick += SKIP_TICKS;
}
interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
/ float( SKIP_TICKS );
render( interpolation );
}
Alguns recursos
- Gaffer em jogos: corrija seu timestep!
- Artigo do loop de jogo do deWitter
- O FPS do Quake 3 afeta a física do salto - supostamente um motivo pelo qual o Doom 3 está bloqueado a 60fps?
- Flixel requer um timestep variável (acho que isso é determinado pelo Flash) enquanto o Flashpunk permite os dois tipos.
- Manual do Box2D § Simulando o mundo do Box2D sugere que ele use etapas de tempo constantes.