(Delta time) Получение 60 обновлений в секунду в Java

Я видел этот код несколько раз.

long lastTime = System.nanoTime();
final double ticks = 60D;
double ns = 1000000000 / ticks;    
double delta = 0;

Приведенный выше код отнимает системное время и сохраняет его в lastTime, 60 тиков должны соответствовать количеству обновлений в секунду.

while(running){
    long now = System.nanoTime();
    delta += (now - lastTime) / ns;
    lastTime = now;
    if(delta >= 1){
        tick();
        delta--;
    }

Занимает now и вычитает lastTime, а затем преобразует его в наносекунды /60. Есть ли какая-то гарантия того, что разница во времени между now а также lastTime к nano более 60 приведет к тому, что дельта будет больше или равна 1, 60 раз в секунду? Я не могу понять почему tick(); будет работать около 60 раз в секунду. Из моих расчетов каждый раз, когда цикл запускается, дельта увеличивается на 0,0025 или около того.

3 ответа

Решение

Не зная, что в tick()Я не могу быть уверен, но я предполагаю, что он также использует 60D пытаться спать в течение правильного количества времени? Итак: нет, нет никакой гарантии, это то, что этот код должен исправить.

Это говорит "Если tick() спал меньше, чем клещ, потом ничего не делал; если он спал на тик или больше, тик один раз ".

Предположительно, если тиканье пройдёт достаточно (например, 80 нс, а затем 80 нс, что означает, что 1-й цикл увеличивает тик, а второй увеличивает его на 2), то в конце концов будет другой цикл, который имеет только дельту 40 нс, заставляя все выравниваться.

Я прокомментировал код немного, чтобы показать вам более ясно, что происходит.

//Get the system time
long lastTime = System.nanoTime();
//Specify how many seconds there are in a minute as a double
//store as a double cause 60 sec in nanosec is big and store as final so it can't be changed
final double ticks = 60D;
//Set definition of how many ticks per 1000000000 ns or 1 sec
double ns = 1000000000 / ticks;    
double delta = 0;

while(running){
//Update the time
    long now = System.nanoTime();
//calculate change in time since last known time
    delta += (now - lastTime) / ns;
//update last known time    
    lastTime = now;
    //continue while delta is less than or equal to 1
    if(delta >= 1){
//Go through one tick        
        tick();
//decrement delta
        delta--;
    }

Теперь я почти уверен, что это именно так, но я не могу сказать наверняка, не видя, что такое tick()

Это гарантирует, что метод tick() выполняется только 60 раз в секунду. Он называется дельта-таймингом и упоминается во всем игровом сообществе. Причина, по которой используется дельта-синхронизация, заключается в том, чтобы игры работали с одинаковой скоростью на всех платформах. Такие вещи, как физика и анимация в играх, должны работать с одинаковой скоростью, независимо от скорости системы. Если у вас медленная система, а в игре нет дельта-синхронизации, физика будет работать медленнее, чем если бы игра работала на быстрой системе.

Как это устроено

  • Выясните, сколько раз вы хотите обновить в секунду, в вашем случае это 60 раз в секунду.

  • найти разрешение языков встроенной функции времени. В вашем коде используется встроенная в Java функция System.nanotime(), которая возвращает длинное значение количества наносекунд, в течение которых система работала.

  • есть 1000000000 наносекунд в секунду, что означает, что разница во времени на один вызов функции tick() равна 1000000000/60. Что составляет примерно 16666666 наносекунд. Это означает, что всякий раз, когда вызывается tick(), программа будет ждать 16666666 наносекунд, прежде чем снова вызовет tick().

  • что вы должны сделать, это найти время между текущим кадром и последним кадром в наносекундах. Это значение, деленное на временной шаг (16666666), даст вам десятичный процент от того, сколько прошло необходимого времени. Если вы добавите этот десятичный процент к дельта-переменной, когда дельта-переменная>= 1, пройдет 1/60 секунды, что означает, что теперь программа может вызывать tick().

  • наконец, вы минус 1 от дельта-переменной. Причина, по которой вы не устанавливаете дельта-переменную в 0, состоит в том, что, возможно, был больший временной шаг, чем 1, и дельта-переменная будет выше 1, что означает, что вам придется учитывать это при следующем цикле и вызове поставить галочку()

Другие вопросы по тегам