Ограничение и вычисление FPS в SDL?

#c #sdl #frame-rate #game-development

#c #sdl #частота кадров #разработка игр

Вопрос:

Я написал этот код, чтобы ограничить SDL-игру до 60 кадров в секунду, является ли это правильным способом реализации количества кадров в секунду?

 int fps=60;
int desiredDelta=1000/fps;  //desired time b/w frames


while (gameRunning)
{

    int starttick=SDL_GetTicks();

    // Get our controls and events
    while (SDL_PollEvent(amp;event))
    {
        if (event.type == SDL_QUIT)
            gameRunning = false;
    }
    window.Clear();

    for(Entityamp; e: entities)
    {
        window.Render(e);
    }

    window.Display();

    int delta=SDL_GetTicks()-starttick;     //actual time b/w frames

    int avgFPS=1000/(desiredDelta-delta);  //calculating FPS HERE

    if(delta<desiredDelta)
    {
        SDL_Delay(desiredDelta-delta);
    }
  
    std::cout<<avgFPS<<std::endl;


}
 

Комментарии:

1. Не ответ на вашу проблему, но может ли случиться так, что вы попытаетесь ограничить рендеринг частотой обновления экрана? Потому что, если это ваше фактическое намерение, вы могли бы просто включить VSync и покончить с этим.

2. Да, я добавил флаг vsync, но я подумал, что вам все равно нужно вручную ограничить fps, верно? Я смотрел учебные пособия codergopheers, и он добавляет временной интервал, я предположил, что это похоже на ограничение частоты кадров

3. Если у вас включена vsync, то фактическое представление результата вашей платформой должно быть заблокировано соответствующим образом (я недостаточно хорошо знаю SDL, чтобы указать вам правильную документацию, увы). Вам все равно нужно отслеживать время, чтобы знать, сколько времени прошло, и при необходимости вычислять обновления мира (чтобы ваша игра не была на 66% быстрее на мониторе с частотой 100 Гц, чем на мониторе с частотой 60 Гц).

Ответ №1:

В играх обычно есть две «частоты кадров», о которых нужно беспокоиться: частота кадров дисплея и частота кадров вашей игровой физики. В идеале вы рисуете с собственной частотой кадров дисплея. Для этого убедитесь, что вы передали SDL_RENDERER_PRESENTVSYNC флаг SDL_CreateRenderer() кому .

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

В качестве альтернативы, вы используете фиксированную частоту кадров для своей физики. Однако, если вы сделаете последнее, вам придется как-то справиться с тем, что две частоты кадров не синхронизированы, но это не решается добавлением SDL_Delay() s . Обычный подход заключается в том, чтобы поток рендеринга интерполировал анимации на основе физики по мере необходимости.

Более практическая проблема в вашем коде заключается в том, что SDL_GetTicks() дает вам время в миллисекундах. Это не очень точно; если ваш дисплей работает со скоростью 60 кадров в секунду, то один кадр занимает 16.66666 … миллисекунд. Ваш расчет будет иметь ошибку до 1 мс, что составляет 6,25% от длины одного кадра. В зависимости от типа игры, это действительно может быть заметно!