Recientemente leí este artículo sobre Game Loops: http://www.koonsolo.com/news/dewitters-gameloop/
Y la última implementación recomendada me está confundiendo profundamente. No entiendo cómo funciona, y parece un completo desastre.
Entiendo el principio: actualizar el juego a una velocidad constante, con lo que quede, renderice el juego tantas veces como sea posible.
Supongo que no puedes usar un:
- Obtenga información para 25 ticks
- Juego de render para 975 ticks
Enfoque ya que recibiría información para la primera parte de la segunda y esto se sentiría extraño? ¿O es eso lo que está pasando en el artículo?
Esencialmente:
while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP)
¿Cómo es eso válido?
Asumamos sus valores.
MAX_FRAMESKIP = 5
Supongamos next_game_tick, que se asignó momentos después de la inicialización, antes de que el bucle principal del juego diga ... 500.
Finalmente, como estoy usando SDL y OpenGL para mi juego, con OpenGL solo para renderizar, supongamos que GetTickCount()
devuelve el tiempo desde que se llamó a SDL_Init, lo que hace.
SDL_GetTicks -- Get the number of milliseconds since the SDL library initialization.
Fuente: http://www.libsdl.org/docs/html/sdlgetticks.html
El autor también asume esto:
DWORD next_game_tick = GetTickCount();
// GetTickCount() returns the current number of milliseconds
// that have elapsed since the system was started
Si ampliamos la while
declaración obtenemos:
while( ( 750 > 500 ) && ( 0 < 5 ) )
750 porque ha pasado el tiempo desde que next_game_tick
fue asignado. loops
es cero como puedes ver en el artículo.
Así que hemos ingresado al ciclo while, hagamos algo de lógica y aceptemos alguna entrada.
Bla bla bla.
Al final del ciclo while, que te recuerdo que está dentro de nuestro ciclo principal del juego es:
next_game_tick += SKIP_TICKS;
loops++;
Actualicemos cómo se ve la próxima iteración del código while
while( ( 1000 > 540 ) && ( 1 < 5 ) )
1000 porque ha transcurrido el tiempo de obtener entrada y hacer cosas antes de llegar a la siguiente ineteración del bucle, donde se recupera GetTickCount ().
540 porque, en el código 1000/25 = 40, por lo tanto, 500 + 40 = 540
1 porque nuestro ciclo ha iterado una vez
5 , ya sabes por qué.
Entonces, dado que este ciclo While depende CLARAMENTE de él MAX_FRAMESKIP
y no del TICKS_PER_SECOND = 25;
modo previsto, ¿cómo se supone que el juego se ejecuta correctamente?
No me sorprendió que cuando implementé esto en mi código, correctamente podría agregar, ya que simplemente cambié el nombre de mis funciones para manejar la entrada del usuario y dibujar el juego a lo que el autor del artículo tiene en su código de ejemplo, el juego no hizo nada .
Coloqué un fprintf( stderr, "Test\n" );
bucle while dentro que no se imprime hasta que termina el juego.
¿Cómo se ejecuta este ciclo de juego 25 veces por segundo, garantizado, mientras se procesa tan rápido como puede?
Para mí, a menos que me falte algo ENORME, parece ... nada.
¿Y no es esta estructura, de este ciclo while, supuestamente ejecutándose 25 veces por segundo y luego actualizando el juego exactamente lo que mencioné anteriormente al comienzo del artículo?
Si ese es el caso, ¿por qué no podríamos hacer algo simple como:
while( loops < 25 )
{
getInput();
performLogic();
loops++;
}
drawGame();
Y contar para la interpolación de otra manera.
Perdona mi pregunta extremadamente larga, pero este artículo me ha hecho más daño que bien. Ahora estoy muy confundido, y no tengo idea de cómo implementar un bucle de juego adecuado debido a todas estas preguntas surgidas.