Я недавно прочитал эту статью об игровых циклах: http://www.koonsolo.com/news/dewitters-gameloop/
И рекомендованная последняя реализация глубоко смущает меня. Я не понимаю, как это работает, и это выглядит как полный беспорядок.
Я понимаю принцип: обновляйте игру с постоянной скоростью, с тем, что осталось, визуализируйте игру столько раз, сколько возможно.
Я так понимаю, вы не можете использовать:
- Получите вход для 25 тиков
- Рендеринг игры за 975 тиков
Подход, поскольку вы будете получать информацию для первой части второй, и это будет странно? Или это то, что происходит в статье?
По существу:
while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP)
Как это вообще действует?
Давайте предположим его ценности.
MAX_FRAMESKIP = 5
Давайте предположим, что next_game_tick был назначен через несколько секунд после инициализации, прежде чем основной цикл игры скажет ... 500.
Наконец, поскольку я использую SDL и OpenGL для своей игры, а OpenGL используется только для рендеринга, давайте предположим, что он GetTickCount()
возвращает время с момента вызова SDL_Init, что и происходит.
SDL_GetTicks -- Get the number of milliseconds since the SDL library initialization.
Источник: http://www.libsdl.org/docs/html/sdlgetticks.html
Автор также предполагает это:
DWORD next_game_tick = GetTickCount();
// GetTickCount() returns the current number of milliseconds
// that have elapsed since the system was started
Если мы расширим while
утверждение, мы получим:
while( ( 750 > 500 ) && ( 0 < 5 ) )
750, потому что время прошло с тех пор, как next_game_tick
было назначено. loops
это ноль, как вы можете видеть в статье.
Итак, мы вошли в цикл while, давайте сделаем некоторую логику и примем ввод.
Yadayadayada.
В конце цикла while, который, напомню, находится внутри нашего основного цикла игры:
next_game_tick += SKIP_TICKS;
loops++;
Давайте обновим, как выглядит следующая итерация кода while
while( ( 1000 > 540 ) && ( 1 < 5 ) )
1000, потому что прошло время получения входных данных и выполнения каких-либо действий, прежде чем мы достигли следующего изменения цикла, где вызывается GetTickCount ().
540 потому что в коде 1000/25 = 40, следовательно, 500 + 40 = 540
1, потому что наш цикл повторялся один раз
5 , ты знаешь почему.
Итак, поскольку этот цикл «ЯДЕР» явно зависит, MAX_FRAMESKIP
а не предназначен, TICKS_PER_SECOND = 25;
как игра должна работать правильно?
Меня не удивило, что когда я реализовал это в своем коде, я мог бы правильно добавить это, просто переименовав свои функции для обработки пользовательского ввода и нарисовав игру так, как это сделал автор статьи в своем примере кода, игра ничего не сделала ,
Я поместил fprintf( stderr, "Test\n" );
внутри цикл while, который не печатается, пока игра не закончится.
Как гарантированно работает этот игровой цикл 25 раз в секунду, и рендерится так быстро, как может?
Для меня, если я не пропустил что-то ОГРОМНОЕ, это выглядит ... ничего.
И разве эта структура, этого цикла while, якобы запускается 25 раз в секунду, а затем обновляет игру именно так, как я упоминал ранее в начале статьи?
Если это так, почему мы не можем сделать что-то простое, как:
while( loops < 25 )
{
getInput();
performLogic();
loops++;
}
drawGame();
И рассчитывать на интерполяцию другим способом.
Простите за мой чрезвычайно длинный вопрос, но эта статья принесла мне больше вреда, чем пользы. Сейчас я сильно запутался - и не знаю, как реализовать правильный игровой цикл из-за всех этих возникших вопросов.