Должен ли игровой цикл основываться на фиксированных или переменных временных шагах? Всегда ли кто-то лучше или правильный выбор зависит от игры?
Переменный шаг по времени
Физическим обновлениям передается аргумент «истекшее время с момента последнего обновления» и, следовательно, они зависят от частоты кадров. Это может означать выполнение расчетов как position += distancePerSecond * timeElapsed
.
Плюсы : гладкие, легче
кодируемые Минусы : недетерминированные, непредсказуемые на очень маленьких или больших шагах
while( game_is_running ) {
prev_frame_tick = curr_frame_tick;
curr_frame_tick = GetTickCount();
update( curr_frame_tick - prev_frame_tick );
render();
}
Фиксированный шаг по времени
Обновления могут даже не принимать «истекшее время», так как они предполагают, что каждое обновление имеет фиксированный период времени. Расчеты могут быть сделаны как position += distancePerUpdate
. Пример включает в себя интерполяцию во время рендеринга.
Плюсы : предсказуемый, детерминированный (проще для синхронизации по сети?), Более четкий код расчета.
Минусы : не синхронизируется для мониторинга v-синхронизации (вызывает дрожание графики, если вы не интерполируете), ограниченная максимальная частота кадров (если вы не интерполируете), трудно работать в рамках, которые предположить переменные временные шаги (например, Pyglet или Flixel )
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 );
}
Некоторые ресурсы
- Торгуйте по играм: исправьте время!
- статья цикла игры deWitter
- FPS в Quake 3 влияет на физику прыжков - по какой причине Doom 3 блокируется до 60 кадров в секунду?
- Flixel требует переменного временного шага (я думаю, это определяется Flash), тогда как Flashpunk допускает оба типа.
- Руководство Box2D § Моделирование мира Box2D предполагает, что он использует постоянные временные шаги.