Paso de tiempo semi-fijo o totalmente fijo?

15

Estoy haciendo un iphone shmup y estoy tratando de decidir qué tipo de bucle de juego usar. Quiero usar un paso de tiempo semi-fijo o un paso de tiempo completamente fijo.

Con un paso de tiempo semi-fijo haré cero o más llamadas de actualización (FIXED_INTERVAL) seguidas de una llamada de actualización (dt) donde dt <= FIXED_INTERVAL por ciclo de juego. Según tengo entendido, los inconvenientes de este método son que mi lógica de actualización física (dt) será más difícil de programar porque básicamente tengo que asumir una variable dt para cada actualización. Y luego también escuché que cada ejecución de mi juego será ligeramente diferente debido a que los valores de coma flotante no son los mismos cada vez.

Luego, con un paso de tiempo completamente fijo, estoy haciendo cero o más llamadas de actualización (FIXED_INTERVAL) seguidas de una llamada de interpolación (dt / FIXED_INTERVAL) donde dt <FIXED_INTERVAL por ciclo de juego.

Entonces, parece que la gran decisión que realmente tengo que tomar es: ¿quiero enfrentar el desafío de implementar una actualización (dt) con una variable dt o quiero enfrentar el desafío de implementar la interpolación?

Ahora, por lo que he leído, la mayoría de la gente dice que use una solución totalmente fija y haga la interpolación. Pero cuando pienso en implementar la interpolación, parece que sería mucho más complejo que una actualización (dt) con dt variable. Esto se debe a que si uso la interpolación tengo que recordar tanto el estado anterior como el estado actual. Entonces, si quiero usar la interpolación, tengo que crear una capa adicional de indirección que abstraiga estados de juego individuales completos. Mientras que con un paso de tiempo semi-fijo donde no tengo que usar la interpolación, no tengo que encontrar una abstracción del estado del juego porque siempre hay un solo estado del juego y son simplemente las "matrices globales" las que representan a mis enemigos y enemigos. balas etc.

Entonces, ¿cuál es la opción más práctica? ¿Lo implemento semi-fijo sabiendo que mis actualizaciones físicas podrían complicarse con la variable dt? ¿O uso completamente fijo e intento obtener una abstracción del estado del juego para poder realizar un seguimiento del estado anterior y el estado actual para realizar la interpolación?

Ryan
fuente
Cubierto bastante aquí: gamedev.stackexchange.com/questions/1589/…
michael.bartnett
1
He leído esa discusión y los enlaces allí varias veces. En realidad es cómo llegué a esta publicación. Mi pregunta tiene que ver principalmente con cómo implementar estados de juego para lograr la interpolación, lo que no se cubre en absoluto en esa discusión.
Ryan

Respuestas:

12

Completamente arreglado

Pierdes la mayoría de los beneficios de un paso de tiempo fijo cuando lanzas un paso variable una vez cada cuadro.

Noel Lopis tiene una gran reseña sobre cómo implementó un paso de tiempo fijo en los juegos de Casey . Como beneficio adicional para usted, él es un desarrollador de iPhone, aunque su técnica no es específica para iPhone.

Algunos puntos destacados del artículo.

  • Usa un acumulador de tiempo.
  • Use una frecuencia física de 120Hz para una velocidad de cuadro de 60Hz.
  • Simule un paso fijo hacia el futuro y use la acumulación de tiempo restante para cambiar el código de dibujo entre el estado físico actual y el estado físico futuro.
  • varias trampas
código_deft
fuente
2

En mi opinión, lo que usted conoce como paso de tiempo "semi-fijo" y "completamente fijo" son, en mi opinión, ambos pasos de tiempo fijos: el dt que está pasando a su updatellamada no cambia entre fotogramas.

Entonces, su pregunta es en realidad "¿quiero implementar la interpolación con el propósito de renderizar?" La respuesta es: probablemente no .

La interpolación es algo que solo querría hacer si su paso de tiempo fijo updatees marcadamente diferente a su paso de tiempo objetivo render. No es raro que los juegos que tienen una updatefase extenuante solo llamen updatea, digamos, 10Hz, pero se procesen a velocidad de fotogramas completa.

Como está escribiendo un shmup de iPhone, ni usted updateni su rendernecesidad requieren un uso intensivo de la CPU; puedes bloquear fácilmente tu velocidad de cuadros a 30Hz o 60Hz, no molestarte con la implementación y aún así tener un juego de aspecto suave.

Blair Holloway
fuente
No lo entiendo ¿Estás diciendo que puedo bloquear el gran dt que calcularía en mi ciclo de juego, que consume mi física? ¿Cómo puedo hacer eso? ¿Puedo hacerlo con CADisplayLink? Quiero decir, ¿qué porcentaje de CPU estás suponiendo que estoy usando? ¿Realmente deberías asumir el juego cerrado loop dt?
Ryan
Lo que digo realmente se reduce a esto: hacer lo menos complicado que funcione.
Blair Holloway
1
Elaboración: utilizando una variable dtpara updateyrender es lo más simple que funcionaría, pero generalmente se evita al usar motores de física por la inestabilidad que causa. Por lo tanto, llamar updatecon un fijo dty renderizar a la misma velocidad (mientras se caen fotogramas si se updateejecuta durante mucho tiempo) es generalmente lo más simple que funcionaría. Escribir código para interpolar objetos entre updatellamadas agrega complejidad a su código; complejidad que está agregando para resolver ningún problema en particular.
Blair Holloway