Фиксированная частота кадров SFML
Есть проект для работы с физикой с использованием sfml, но на разных устройствах программа работает по-разному. Как задать фиксированные промежутки времени между обновлениями?
Код:
#include <SFML/Graphics.hpp>
const int WIDTH = 800, HEIGHT = 600;
int main()
{
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "Title", sf::Style::Titlebar | sf::Style::Close);
sf::Clock clock;
while (window.isOpen())
{
float dt = clock.restart().asSeconds();
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
//update
update(dt);
//скорость += ускорение * dt
//позиция += скорость * dt
window.clear();
//render
render(window);
window.display();
}
return 0;
}
Пробовал window.setFramerateLimit(), но это ограничивает только максимальную частоту кадров.
Ответы (2 шт):
Автор решения: a_nR1085__i
→ Ссылка
//DELTA_TIME = 1.0f / 60.0f
window.setFramerateLimit(1.0f / DELTA_TIME);
while (window.isOpen())
{
float dt = clock.restart().asSeconds();
//update
unsigned int nr = std::ceil(dt / DELTA_TIME);
for (int i = 0; i < nr; i++)
update(DELTA_TIME);
window.clear();
//render
render(window);
window.display();
}
Автор решения: KoVadim
→ Ссылка
Так как внутрицикловая логика может выполнятся с разной скоростью, то нужно вручную ее "подкорректировать". Обычно это делается так
float want_fps = 50;
while (need_run) {
int start = getCurrentTime();
// логика
//....
// отрисовка
//....
int time_to_sleep = (1.f/want_fps - (stop-start);
if (time_to_sleep > 0) {
sleep(time_to_sleep);
}
}
перепишем это на sfml
float want_fps = 50;
sf::Clock loop_timer;
while(....) {
// логика и отрисовка
// ....
sf::Int32 frame_duration = loop_timer.getElapsedTime().asMilliseconds();
sf::Int32 time_to_sleep = int(1000.f/want_fps) - frame_duration;
if (time_to_sleep > 0) {
sf::sleep(sf::milliseconds(time_to_sleep));
}
loop_timer.restart();
}