В данный момент использую такой код для вызова обновления физики в главном цикле:
While (!quit) { currentTime = std::chrono::high_resolution_clock::now( ); float deltaTime = std::chrono::duration<float, std::chrono::seconds::period>( currentTime - startTime).count( ); if ( deltaTime > prevUpdateTime + dt) { prevUpdateTime += dt; updatePhysics( dt); } // Рендер }
Это хорошо работает на мощных машинах. Но если фпс просаживается даже на самую малость, то получается "заикание" - изображение как бы на малую долю секунды "замирает". Как усовершенствовать вызов обновления физики чтобы такого не было?
Замени это:
if (deltaTime > prevUpdateTime + dt) { prevUpdateTime += dt; updatePhysics( dt); }
while (prevUpdateTime < currentTime) { prevUpdateTime += dt; updatePhysics( dt); }
Mikle
> Замени это:
Не повлияло.
Нагуглил, что в этом случае поможет только интерполяция между предыдущим и текущим состоянием кадра. Пипец, это надо считать и хранить все предыдущие позиции и повороты, и местами не только их.
MikeNew
Посмотри последнюю правку. У меня так, и оно нормально работает, специально добавлял сильные тормоза и проверял.
Mikle
> while (prevUpdateTime < currentTime)
prevUpdateTime - это флоат
currentTime - это std::chrono::time_point
не получится сравнить.
Набросай пожалуйста псевдокод, как у тебя сделано.
Const DTime As Double = 1 / 200 Dim OldTime As Double While Running Dim t As Double t = QTime ' точное текущее время в Double While t - OldTime > DTime Tick ' расчёт физики OldTime = OldTime + DTime Wend Render Wend
Самая лучшая физика для игр, это физика умеющая работать в мультиплеерной сетевой игре. Именно в этом направлении вы найдёте все необходимые вам правильные ответы.
физика должна обновляться кратно рендеру, но, желательно, не слишком во много раз.
Можно даже сделать чтобы программа сама определяла эту кратность для данной машины.
аккумулятор сглаживающий сколько реально занял тик где?
а фиксированный шаг физики?
#!
> а фиксированный шаг физики?
В моём варианте так и есть, DTime - константа.
Проблема может возникнуть в случае если за несколько кадров рендера накапливается еще один кадр физики. При этом возникает "скачек" - объекты на данном кадре сдвинутся в два раза быстрее. Для пользователя это будет выглядеть, как будто объекты время от времени подергиваются. Другая проблема - если расчет физики достаточно тяжелый и при накоплении дополнительного кадра физики возникает просадка fps.
MikeNew
> Нагуглил, что в этом случае поможет только интерполяция между предыдущим и
> текущим состоянием кадра. Пипец, это надо считать и хранить все предыдущие
> позиции и повороты, и местами не только их.
Можно ещё экстраполяцию попробовать — то есть, взять последние положение и скорость объекта, и подвинуть его с учетом неизрасходованного кусочка времени кадра, оставшегося в аккумуляторе.
На глаз может быть практически неотличимо от интерполяции.
Mirrel
Не, физику лучше раз и навсегда приколотить к какой-то заданной частоте. Потому что от неё зависит поведение игры: например, с одной частотой ты можешь куда-то допрыгнуть, а с другой — нет.
BUzer, да, я уже это понял. Что физику можно раза в два ускорить (максимально), но и этого делать не стоит. Значит должна просто соответствовать частоте кадров.
В противном случае, при больших нагрузках на машине слабже будут проявляться непредвиденные глюки. И вероятно не решаемые.