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?
Respuestas:
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.
fuente
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
update
llamada 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
update
es marcadamente diferente a su paso de tiempo objetivorender
. No es raro que los juegos que tienen unaupdate
fase extenuante solo llamenupdate
a, digamos, 10Hz, pero se procesen a velocidad de fotogramas completa.Como está escribiendo un shmup de iPhone, ni usted
update
ni surender
necesidad 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.fuente
dt
paraupdate
yrender
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, llamarupdate
con un fijodt
y renderizar a la misma velocidad (mientras se caen fotogramas si seupdate
ejecuta durante mucho tiempo) es generalmente lo más simple que funcionaría. Escribir código para interpolar objetos entreupdate
llamadas agrega complejidad a su código; complejidad que está agregando para resolver ningún problema en particular.