Ваш FPS может (и обычно будет) варьироваться, поэтому подсчет кадров не является хорошей идеей.
Предположим, этот пример показывает, как это может вас укусить:
Ваше приложение работает с частотой 60 FPSи ваше время кадра составляет 16,58 мс.Это значит, что объект должен находиться на экране в течение 2 секунд, вам придется нарисовать объект за 120 кадров.Легко, поехали!
Рисование объекта добавляет 0,1 мс, что дает общее время кадра 16,68 мс.Ох, ш * т.Теперь у вас есть 30 FPS, и ваш объект отображается в течение 4 секунд ...
Используйте правильное время , чтобы решить, рисовать ваш объект или нет.Когда вы пришли к выводу, что время вашего объекта истекло, просто установите флаг, чтобы вы не рисовали его (или удалите его из графа сцены, если он у вас есть, или удалите его, или что-то еще).
Это можно сделать разными способами:
- Под Windows
- Использовать
SetTimer
, который отправит сообщение в очередь сообщений вашего окна.Когда вы получаете уведомление WM_TIMER, установите для флага do_draw
объекта (или как вы хотите его называть) значение false. - Если вы уже используете
WaitFor(Single|Multiple)Object
где-то один раз в каждом кадре, выполните CreateWaitableTimer
,и подожди на этом тоже.Вы можете использовать MsgWaitForMultipleObjectsEx
для закачки и ожидания сообщений за один раз, и одновременно проверять APC. - Ничто не мешает вам читать время вручную один раз за кадр.
GetTickCount
один раз, добавьте 2000 и сделайте if(new_count <= old_count + 2000) draw_object()
.Хотя точность GetTickCount
ужасна (несколько десятков миллисекунд), это не имеет значения при ожидании в течение 2 секунд.
- Под Linux
- Использование
timerfd
и epoll
для проверки готовности или установите timerfd
на неблокирование и посмотрите, возвращает ли чтение из него EAGAIN - Используйте
clock_gettime
и сделайте это вручную (как с GetTickCount
) - Использование
setitimer