Я хочу, чтобы что-то происходило каждые N секунд, как бы я это сделал? Может быть, использовать таймер, но как?
game-design
timer
user2957632
источник
источник
Ответы:
Обычный подход для этого заключается в использовании цикла обновления и дельта-времени.
Это предполагает, что у вас есть доступ к
deltaTime
переменной. Дельта-время - это просто время, прошедшее с последнего кадра. Многие движки будут иметь это в наличии, или вы можете узнать больше о настройке своего здесь .источник
В большинстве языков вам нужно запустить часы с помощью какого-либо вызова функции по аналогии с
clock.startTimer()
тем, как вы входите в основной цикл. Затем вы должны сохранить значение времени часов перед тем, как ввести основной цикл в переменную с такой функциейtime = clock.getTime()
. Сохраните время вашего шага в переменнойn
.В вашем основном цикле проверка, которую вы хотите сделать, является чем-то вроде
Примечание: я не уверен, на каком языке / библиотеке вы смотрите, так что это всего лишь общий алгоритм, который я придумал не покладая рук. Это может не совсем соответствовать вашим потребностям. Некоторые языки / библиотеки требуют, чтобы вы создали объект часов, в то время как другие вы можете просто сделать вызов функции напрямую.
Согласно комментариям ниже, вы должны быть осторожны с проблемами многопоточности в зависимости от того, какой язык вы используете. Вы также должны использовать двойной поплавок для хранения
time
.источник
time
будет храниться прошедшее игровое время, он должен использовать формат с плавающей запятой двойной точности.Как уже отмечалось в других ответах, реализация таймера может быть выполнена путем увеличения сохраненного значения на каждый кадр
deltaTime
и сравнения его с ожидаемой продолжительностью. Для полноты я добавлю код, который очень похож на другие ответы:То, как вы хотите справиться с
// Run code.
частью, зависит от вас. Возможно, у вас естьTimer
класс, экземпляр которого принимаетdelegate
(C #) илиcallback
(C ++) и вызывает его по истечении таймера. Кроме того, приостановка таймера является вопросом удаления его из цикла обновления.Альтернативный подход заключается в том, чтобы отметить время запуска таймера и вместо этого выполнить вычисление прошедшего времени по требованию:
Этот стиль дает немного больше контроля пользователю таймера. Сама структура не заботится о том, что делать, когда истекшее время достигает определенной точки; это даже не обновление. Пользователь может просто запросить истекшее время, когда это необходимо. Этот паттерн имеет неприятный побочный эффект - он не подходит для отладчика. Системное время продолжается, так как ваша программа останавливается на отладчике, поэтому таймеры, подобные этому, будут вести себя по-разному при переходе между программами. Потенциальным решением этой проблемы является сохранение значения истекшего времени для конкретной программы, которое обновляется каждый кадр с использованием системных дельт времени.
Я думаю, что наиболее важными являются две причуды синхронизации на компьютере, особенно когда речь идет о разработке игр. Первый - это точность с плавающей запятой, а второй - собственное разрешение таймера.
Вы заметите, что во втором примере я использовал
double
тип вместо afloat
, как и в первом примере (имя типа, конечно, зависит от языка, который вы используете). Причиной этого является второй пример - хранение общего прошедшего игрового времени . Если игра остается запущенной в течение очень долгого времени, значения формата с плавающей запятой одинарной точности будут иметь недостаточную точность для точного измерения истекшего времени , что приведет к проблемам со стабильностью. Первый пример подходит для использованияfloat
типа, если не ожидается большой продолжительности.На другом конце спектра, если ожидаемое время обновления достаточно мало, вы, возможно, не сможете достичь его изначально, в зависимости от того, как вы получаете системное время. Таймеры часто зависят от разрешения таймера ОС, на которой вы работаете. Например, разрешение таймера по умолчанию в Windows 7 и ниже составляет 15,6 мс . Это означает, что наименьшая точность таймера, которую вы могли бы достичь, используя такие функции, как
timeGetTime
илиGetTickCount
, составляет 15,6 мс, если вы не измените разрешение таймера ( с этим тоже связаны опасности ).Что ж, это оказалось немного долго, но это важные вещи, о которых следует помнить при реализации таймеров.
источник