Застрянь посередине
Осталось решить всего одну проблему — остаточное за-
паздывание. Мы обновляем игру фиксированными вре-
менными шагами, но рендеринг осуществляется в слу-
чайные моменты времени. С точки зрения пользователя,
это значит, что рендеринг происходит между обновле-
ниями. Посмотрите на изображенную шкалу времени
(рис. 9.3).
Рис. 9.3.
Временная шкала, показывающая, когда происходит
обновление игры и рендеринг
Как вы можете увидеть, обновления происходят
с равными фиксированными интервалами. В отличие
от рендеринга. Он происходит реже обновлений, ин-
тервалы также неодинаковы. Но это нормально. Про-
блема в том, что рендеринг происходит не в момент
Я оставил это за рам-
ками книги, но вы мо-
жете защититься от
этого, выйдя из внутрен-
него цикла обновления
после достижения мак-
симального количества
итераций. В таком слу-
чае игра замедлится, но
это лучше, чем если бы
она полностью заблоки-
ровалась.
174
Игровой цикл (Game Loop) —
Паттерны программирования игр
обновления. Посмотрите, когда произойдет третий рен-
деринг. Он прямо между обновлений (рис. 9.4).
Рис. 9.4.
Рендеринг прямо между двух кадров обновления
Снова представьте пулю, летящую по экрану. В пер-
вый кадр обновления она слева. Во второй — справа.
Рендеринг происходит между этими двумя момента-
ми, так что пользователь ожидает увидеть пулю где-то
по центру экрана. При нашей текущей реализации в мо-
мент обновления она все еще будет слева. А значит, дви-
жение будет выглядеть дерганым и прерывистым.
Очень удобно
знать
, как далеко мы от кадра обнов-
ления, когда начинается рендеринг: эта информация
хранится в переменной
lag
. Мы выходим из цикла об-
новления, когда это значение меньше, чем значения
временного шага обновления, но не когда оно равно
нулю
. Так насколько далеко мы ушли? То есть насколько
мы близко к следующему кадру обновления.
Когда начинается рендеринг, мы передаем в его
функцию следующее значение:
render(lag / MS_PER_UPDATE);
Функция рендеринга знает о каждом объекте игры
и его
скорости
. Скажем, пуля находится на расстоянии
в 20 пикселей от левого края экрана и летит со скоро-
стью 400 пикселей за кадр. Если мы находимся ровно
между кадрами, то передадим в функцию рендеринга
значение 0,5. Поэтому пуля отобразится на полкадра
вперед, на 200 пикселей. Та-дам, плавное движение.
Конечно, экстраполяция может оказаться неверной.
Когда мы рассчитываем следующий кадр, то можем
обнаружить, что пуля наткнулась на препятствие или
Мы делим на значение
MS_PER_UPDATE
, чтобы
нормализовать значе-
ние. Значение, переда-
ваемое
render()
, бу-
дет варьироваться от 0
(прямо в момент преды-
дущего обновления)
до 1.0 (в следующий
кадр) независимо от ве-
личины временного
шага. Таким образом
функции рендеринга
не важна эта величина,
она работает со значе-
ниями от 0 до 1.
Do'stlaringiz bilan baham: |