Цикл ограничения по времени до 30 «FPS» использование дельта-переменной переполнения стека

Мне в основном нужен цикл while, чтобы работать только на 30 «FPS».
Мне сказали сделать это:
«Внутри цикла while создайте deltaT, а если этот deltaT меньше 33 миллисекунд, используйте sleep (33-deltaT)».

Но я действительно не был уверен, как инициализировать дельту / что установить для этой переменной. Я также не мог получить ответ от человека, который предложил это.

Я также не уверен, почему значение во сне 33 вместо 30.

Кто-нибудь знает, что я могу с этим сделать?

Это в основном для того, чтобы игровой сервер обновлял игроков со скоростью 30 FPS, но поскольку я не выполняю рендеринг на сервере, мне нужен способ просто перевести код в спящий режим, чтобы ограничить число повторений, которые он может выполнять в секунду, иначе обрабатывать игроков слишком быстро.

3

Решение

Вам в основном нужно сделать что-то вроде этого:

int now = GetTimeInMilliseconds();
int lastFrame = GetTimeInMilliseconds();

while(running)
{
now = GetTimeInMilliseconds();
int delta = now - lastFrame;
lastFrame = now;

if(delta < 33)
{
Sleep(33 - delta);
}

//...
Update();
Draw();
}

Таким образом, вы вычисляете количество миллисекунд, прошедших между текущим кадром и последним кадром, и если оно меньше 33 миллисекод (1000/30, 1000 миллисекунд в секунду, деленное на 30 FPS = 33,333333 ….), то вы спите до 33 миллисекунды прошли. Имеет для GetTimeInMilliseconds() а также Sleep() Функция зависит от используемой вами библиотеки и / или платформы.

4

Другие решения

C ++ 11 предоставляет простой механизм для этого:

#include <chrono>
#include <thread>
#include <iostream>

using namespace std;
using namespace std::chrono;

void doStuff(){
std::cout << "Loop executed" << std::endl;
}

int main() {

time_point<system_clock> t = system_clock::now();

while (1) {
doStuff();
t += milliseconds(33);
this_thread::sleep_until(t);
}
}

Единственное, о чем вам следует знать, это то, что если одна итерация цикла занимает больше времени, чем 33 мс, следующие две итерации будут выполняться без паузы между ними (пока t не догонит реальное время), что может не быть тем, что вы хотите.

2

Гленн Фидлер написал хорошую статью на эту тему несколько лет назад. Взлом с sleep() не очень точный, вместо этого вы хотите запускать свою физику фиксированное число раз в секунду, чтобы ваша графика работала свободно, а между кадрами вы делаете столько фиксированных временных шагов, сколько прошло времени.

Код, который следует ниже, поначалу выглядит пугающе, но, как только вы поймете идею, он станет простым; Лучше прочитать статью полностью.

Исправьте ваш временной шаг

double t = 0.0;
double dt = 0.01;

double currentTime = hires_time_in_seconds();
double accumulator = 0.0;

State previous;
State current;

while ( !quit )
{
double newTime = hires_time_in_seconds();
double frameTime = newTime - currentTime;
if ( frameTime > 0.25 )
frameTime = 0.25;
currentTime = newTime;

accumulator += frameTime;

while ( accumulator >= dt )
{
previousState = currentState;
integrate( currentState, t, dt );
t += dt;
accumulator -= dt;
}

const double alpha = accumulator / dt;

State state = currentState * alpha +
previousState * ( 1.0 - alpha );

render( state );
}

Если он переходит в автономный режим, должно быть доступно несколько резервных копий; однако я помню Gaffer на играх уже много лет.

2
По вопросам рекламы [email protected]