Представьте, что у вас очень простая игра, в которой просто шарик движется по экрану. Без обновлений, основанных на времени, он перемещается так же быстро, как и вы.
Что вы хотите сделать, это выяснить, сколько времени прошло (в долях. Я обычно измеряю в секундах, так что физические уравнения лучше соответствуют.) При обновлении вместо чего-то вроде этого:
ballPosition += ballVelocity
У вас будет это:
ballPosition += ballVelocity * timeElapsed
Это означает, что для более высокой частоты кадров timeElapsed
будет ниже, что, следовательно, будет меньше перемещать мяч. Более низкая частота кадров означает, что timeElapsed
будет больше, и шар будет двигаться больше за кадр.
В конце концов, мяч будет перемещаться на одинаковое расстояние независимо от частоты кадров. Частота обновления 60 FPS делает timeElapsed
равной 0.01666667f
, а частота обновления 30 FPS делает ее 0.03333333f
. Вы можете видеть, как при 60 кадрах в секунду, затраченное время составляет половину от 30 кадров в секунду, но поскольку оно в два раза быстрее, это то же самое число.
Обычно я передаю timeElapsed
в качестве аргумента любым функциям, зависящим от времени. Хорошим следствием этого является то, что вы можете замедлить или ускорить свою игру, умножив прошедшее время на значение. Вы также можете применить это к отдельным компонентам. Это также хорошо работает, если вы переключаетесь на модель с ограничением фреймов, потому что вы фактически просто заставляете timeElapsed
быть константой. Псевдо-код:
while (gameRunning)
{
const float timeElapsed =
timer.elapsed(); // elapsed returns the number of seconds
// passed since it was last called
// GlobalTimeScale is 1 for normal time
game.update(timeElapsed * GlobalTimeScale);
game.draw();
}
Чтобы узнать время, GetTickCount
должно работать. Вы также можете взглянуть на QueryPerformanceCounter
для большей точности, хотя могут возникнуть проблемы с несколькими ядрами.