Як отримати та використовувати дельта-час


14

У моїй грі є миші, які дивляться і гуляють, але вони дуже повільні і важкі у використанні. Я думаю, що це тому, що я використовую фіксовану швидкість. Я чув, що у великих проектах розробники використовують дельта-час. Як обчислити дельта-час у клейові? Як обчислити швидкість за допомогою дельта-часу?


Відповіді:


18

"Дельта-час" - це час, що минув між двома оновленнями кадру (але він може бути використаний і в інших контекстах; зазвичай це результат віднімання часу).

Ви можете отримати час дельти в глухоті за допомогою методу glutGet та параметра GLUT_ELAPSED_TIME, а також деяких операцій.

У наступному рядку повертається кількість мілісекунд з моменту виклику glutInit (або першого виклику до glutGet (GLUT_ELAPSED_TIME)):

int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);

Отже, якщо ви реєструєте поточний timeSinceStart в кожному циклі візуалізації, ви можете знати deltaTime, віднісши старий до нового.

int oldTimeSinceStart = 0;

while( ... )
{
     int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);
     int deltaTime = timeSinceStart - oldTimeSinceStart;
     oldTimeSinceStart = timeSinceStart;

     //... stuff to update using deltaTime
}

Ви також можете зробити це майже так само, використовуючи бібліотеку ctime C / C ++ з тактовою частотою () та макроконстантним виразом CLOCKS_PER_SEC, яка визначає співвідношення між годинником та секундою.


В основному, ви можете використовувати deltaTime для оновлення своїх рухів у співвідношенні до цього минулого часу замість використання фіксованого значення часу. Таким чином, швидкість руху вашого персонажа повинна бути майже однаковою, якщо ваша програма працює зі швидкістю 60 кадрів в секунду або якщо вона працює в 10 кадрів в секунду.


Ось невеликий приклад: припустимо, ви хочете щось переміщувати на 10 одиниць щосекунди по осі x. Ви можете зробити щось подібне (якщо deltaTime дійсно використовує мілісекунди).

Position.x += 10/1000 * deltaTime;

Таким чином, незалежно від того, чи була ваша програма оновлена ​​2 або 100 разів, через 1 секунду позиція повинна бути майже однаковою, а на грі менш впливає низький кадр в секунду невеликого комп'ютера, ніж якщо вона використовує фіксовані значення.

  • З фіксованими значеннями ==> низький кадр в секунду = менше оновлень = повільні рухи, тоді як високий кадр в секунду = більше оновлень = дуже швидкі рухи.

  • З deltaTime ==> "майже" однакові рухи.


Нарешті, вам слід прочитати крок фіксованого часу та крок змінної часу на gamedev.stackexchange.


Він повертає мілісекунди як ціле число? Валовий і, можливо, недостатній. Мені завжди доводилося використовувати таймери для платформи, а потім просто уникав GLUT, як чуми, оскільки це супер не чудово для ігор.
Шон Міддлічч

@Sean я також не використовую GLUT, але це було в параметрі питання, тому я відповів на це на увазі;) Однак мене заінтригує ваша позиція щодо "недостатності" int для обробки мілісекунд в іграх . positive intЗазвичай йдуть до 2.147.483.647 , якщо вони підписані і до 4.294.967.295 , якщо беззнаковое ... так що навіть якщо ми розглянемо один менше, 2.147.483.647 мілісекунди майже 25 днів ... Це повинно бути цілком достатньо , щоб працювати з більшістю гри таймери, і навіть якщо цього недостатньо, ми все ще можемо розумно використовувати unsigned int(~ 50 днів) або навіть long long(як я зазвичай це роблю).
Valkea

1
@Valkea Справа не в максимумі, а в роздільній здатності. Оскільки один кадр зі швидкістю 60 кадрів в секунду становить всього 16 2 / 3rds мс, точність 1 мс (від подання мілісекунд як цілих чисел) являє собою граничну помилку більше 5% - більш ніж достатньо, щоб викинути симуляції далеко з удару. Ціле число мікросекунд було б терпімим, але мілісекунди занадто грубі.
Стівен Стадницький

Так, вам потрібні підмілісекундні таймінги для багатьох речей і таймер високої роздільної здатності, щоб знайти те, чого GLUT не забезпечує (про що я знаю). Непогано просто написати невеликий код платформи, який потрібно використовувати QueryPerformanceCounterдля Windows та gettimeofdayбільшості інших. Вам доведеться забруднити руки і націлитись на трохи більше, ніж найменш поширений знаменник API платформ, особливо на C та C ++.
Шон Міддлічч

Така точність корисна не для всіх ігор. Однак це дуже цікаве пояснення, яке повністю відповідає моєму допиту щодо вашої точки зору щодо int та годинників. Мені ніколи не потрібні були високоточні годинники, але я думаю, що настав час поглибити свої знання з цього питання. Дякую;)
Valkea
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.