Создание программы на основе таймера, а не зависит от частоты кадров? - PullRequest
1 голос
/ 16 ноября 2009

У меня есть игровой движок для работы в классе. В настоящее время его рендеринг зависит от частоты кадров, и одним из требований является переход к зависимости на основе таймера. Я не уверен, как определить, где он полагается на частоту кадров. Я не уверен, что искать. Я понимаю, что мне нужно каким-то образом включить таймер (GetTickCount?), Чтобы выполнить это, но я не уверен, как часто обновлять это тоже.

Я не хочу, чтобы мне передавали код, возможно, какие-то полезные рекомендации?

Ответы [ 4 ]

5 голосов
/ 16 ноября 2009

Представьте, что у вас очень простая игра, в которой просто шарик движется по экрану. Без обновлений, основанных на времени, он перемещается так же быстро, как и вы.

Что вы хотите сделать, это выяснить, сколько времени прошло (в долях. Я обычно измеряю в секундах, так что физические уравнения лучше соответствуют.) При обновлении вместо чего-то вроде этого:

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 для большей точности, хотя могут возникнуть проблемы с несколькими ядрами.

1 голос
/ 16 ноября 2009

Я использовал исправил ваш временной шаг с некоторым успехом

Затем возникает проблема с отслеживанием любой задержки ... и замедлением работы, если компьютер не успевает.

0 голосов
/ 16 ноября 2009

Если вы не уверены, где используются частоты кадров, это почти наверняка подразумевается в вашем основном цикле. Если у вас есть вызов функции рендеринга в вашем основном цикле, а рендеринг занимает много времени, то «частота цикла» вашего основного цикла равна частоте кадров, верно? Однопоточное выполнение означает все, что обрабатывается в цикле , влияет на частоту кадров.

0 голосов
/ 16 ноября 2009

Возможный цикл игры с псевдокодом:

constant TIMETHRESHOLD xxxx // nanoseconds to pass between executions of game loop

while true loop
    if getTime() - previousTime > TIMETHRESHOLD
        previousTime = getTime();
        // Execute game logic here
    end if
end loop

Дело в том, что у вас может быть разный TIMETHRESHOLD для разных частей игровой логики. Например, вам может понравиться частота кадров 60 кадров в секунду, но если физический движок «работает» на скорости 30 кадров в секунду, этого достаточно ... такого рода вещи. С быстрым аппаратным обеспечением оно будет работать по назначению, а с более медленным (которое не может соответствовать требованиям времени) оно будет работать так же быстро, как и в любом случае. Конечно, это простой, однопроцессный пример.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...