Мне в основном нужен цикл while, чтобы работать только на 30 «FPS».
Мне сказали сделать это:
«Внутри цикла while создайте deltaT, а если этот deltaT меньше 33 миллисекунд, используйте sleep (33-deltaT)».
Но я действительно не был уверен, как инициализировать дельту / что установить для этой переменной. Я также не мог получить ответ от человека, который предложил это.
Я также не уверен, почему значение во сне 33 вместо 30.
Кто-нибудь знает, что я могу с этим сделать?
Это в основном для того, чтобы игровой сервер обновлял игроков со скоростью 30 FPS, но поскольку я не выполняю рендеринг на сервере, мне нужен способ просто перевести код в спящий режим, чтобы ограничить число повторений, которые он может выполнять в секунду, иначе обрабатывать игроков слишком быстро.
Вам в основном нужно сделать что-то вроде этого:
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()
Функция зависит от используемой вами библиотеки и / или платформы.
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 не догонит реальное время), что может не быть тем, что вы хотите.
Гленн Фидлер написал хорошую статью на эту тему несколько лет назад. Взлом с 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 на играх уже много лет.