|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
02.02.2017, 09:23 | #1 |
Пользователь
Регистрация: 13.05.2007
Сообщений: 60
|
Неправильно работает таймер?
Скорее всего глупый вопрос, но при написании игры и перестроении концепции времени в ней заметил интересную штуку. Далее решил поэкспериментировать и вот что получил: на форме есть обычный дельфовый таймер, кнопка и мемо.
Код:
|
02.02.2017, 09:55 | #2 |
Высокая репутация
СуперМодератор
Регистрация: 27.07.2008
Сообщений: 15,551
|
Таймер не считает с точностью до 1 мс, у него дискретные интервалы. Не помню точно, какой период, допустим, 20 мс. Это означает, что чаще 20 мс срабатывать он не сможет (например, поставите 1 мс, а срабатывать будет каждый 20 мс). В итоге если ставите 50 мс, то срабатывает каждый 60 мс, то есть ближайшее значение, попадающее в период.
Провел эксперимент, вот код, позволяющий вычислить период: Код:
E-Mail: arigato.freelance@gmail.com
Последний раз редактировалось Arigato; 02.02.2017 в 10:07. |
02.02.2017, 10:31 | #3 |
Старожил
Регистрация: 15.02.2010
Сообщений: 15,709
|
1 мс было на старых системах, с 8.1 0.5; так же стоит учесть, что на серверных ОС квант все рано оставили большим.
Если нужна такая точность то вам в сторону https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx |
02.02.2017, 10:58 | #4 |
Лис
Старожил
Регистрация: 18.09.2015
Сообщений: 2,409
|
fanlis
Это особенность Windows таймер на сообщениях работает как захочется левой пятки ведущего разработчика майкрософт. С деланно это для оптимизации работы системы в сторону энергопотребления. В параллели на одном ядре у вас крутиться много программ. Чем меньше раз сработает таймер тем меньше времени съест ваше приложение и его можно будет потратить на остальные приложения. С ростом памяти стало больше приложений и в современных ОС таймер этот притормаживается программно. Показания таймера на сообщениях(стандартный дельфийский). Зависит от числа запущенных программ. производительности вашего процессора и числа ядер. А также от разных ОС и более того от того главный поток или побочный. В побочном быстрее в 2 раза. Для игр стоит использовать мультимедийный таймер. Он уже будет гарантированно работать с точностью 15,16 мс. И при настройке системы 1 мс. timeGetTime, timeKillEvent, and timeSetEvent timeBeginPeriod(1); // Устанавливаем время срабатывания мультимидийного таймера в 1мс Этот параметр влияет на все программы в ОС. Так что не удивляйтесь если другая программа сделала это раньше вас. Arigato А ваш пример неверный так как вы используете менее точный таймер чем ТС. GetTickCount - всегда даёт гранулярность 15.16 мс QueryPerformanceFrequency - как повезёт но обычно либо 3 579 545 Гц либо 14 318 180 Гц либо порядка 2,4 ГГц fanlis При большой загрузки ОС может переносить программу с ядра на ядро и у вас будут разные значения QueryPerformanceCounter. В плоть до получения отрицательной разницы Coun2-Coun1 p51x Подтверждения про квант времени я не нашёл, не наблюдалось. Если параметр и влиял, то только в NT3 или NT4 или Win95. Win98 Win2000 я проверял - там этот параметр не влияет там влияют другие параметры описанные в предыдущем сообщении.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал . Последний раз редактировалось Вадим Мошев; 02.02.2017 в 11:53. |
02.02.2017, 11:28 | #5 |
Пользователь
Регистрация: 13.05.2007
Сообщений: 60
|
А как вообще лучше использовать таймер в игре? Вот, например, есть 2D игра, персонаж идет с одной скоростью, бежит с другой, картинки анимации движения меняются с третьей,падает перс с четвертой скоростью и т.д. Есть еще анимация, не связанная с персонажем.
Для всего этого: 1. делать отдельные таймеры? 2. Один таймер и менять у него интервал? 3. Один таймер с постоянным интервалом, но для каждой анимации вычислять прошедшее время. По первому пункту получается много таймеров и возникает путаница когда какой включать, какой выключать. По второму пункту я пробовал, но в конец запутался со сменой интервалов. И для разных объектов со своей анимацией это не подходит. Попробовал третий пункт и столкнулся с проблемой данной темы. Т.е. допустим у меня картинки анимации перса меняются каждые 80 мс. Таймер у меня с интервалом 20 мс. И есть счетчик последней смены картинки. Каждый такт таймера я увеличиваю счетчик. Но сначала я увеличивал его на интервал (20), потому что думал, что таймер срабатывает каждые 20 мс (а на самом деле 30 мс), т.е. на каждом такте я получал погрешность в 10 мс и суммарная задержка сильно выросла. Потом я стал увеличивать счетчик на рассчитанное время такта (QueryPerformanceCounter), но в этом случае картинки сменяются не равномерно. Как вообще это делается? |
02.02.2017, 11:57 | #6 | ||
Старожил
Регистрация: 09.01.2008
Сообщений: 26,229
|
Цитата:
Цитата:
в таймере получайте текущее время из системы и отталкивайтесь от него. а в каждом объекте храните время следующей обработки (ну или скорость изменения координат - если это движение). |
||
02.02.2017, 12:28 | #7 |
Высокая репутация
СуперМодератор
Регистрация: 27.07.2008
Сообщений: 15,551
|
Да, действительно, сам GetTickCount не выдает разность меньше 15. Значит мой тест неверный.
В качестве примера: Код:
E-Mail: arigato.freelance@gmail.com
|
02.02.2017, 16:48 | #8 |
Лис
Старожил
Регистрация: 18.09.2015
Сообщений: 2,409
|
Лучше один таймер. Тобишь 3 вариант.
При каждом срабатывание таймера вычисляете разницу времени dt. Её умножаете на скорость персонажа и соответственно на столько и смещаем его dx:=dt*V; x:=x+dx; Номер кадра тоже вычисляете исходя из dt, round(dt) mod Count. Если процесс будет притормаживать соответственно это позволит при анимации пропустить ряд кадров.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал . |
02.02.2017, 18:40 | #9 |
Лис
Старожил
Регистрация: 18.09.2015
Сообщений: 2,409
|
https://m.habrahabr.ru/post/136878/
Отличная статья, только нечитайте примечания глупого переводчика. И статья не всё охватывает, есть куда рости что доделать.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал . |
03.02.2017, 03:12 | #10 |
ПШП
Участник клуба
Регистрация: 15.07.2013
Сообщений: 1,872
|
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Программа неправильно работает | HaKeRR | Помощь студентам | 1 | 05.12.2014 23:51 |
Неправильно работает таймер | Юшков | Компоненты Delphi | 9 | 07.11.2011 14:42 |
TextRect работает неправильно | bbk_serg | БД в Delphi | 16 | 10.08.2010 21:11 |
Скрипт неправильно работает | aleksa76 | JavaScript, Ajax | 4 | 21.05.2008 17:47 |
Запрос неправильно работает... | yulia | БД в Delphi | 0 | 27.05.2007 20:41 |