Есть ли лучшее решение, чем setInterval, когда мне нужно, чтобы интервал был очень точным во времени?

1

Я создаю браузерную игру, похожую на Guitar Hero. Как это работает, setInterval установлен для выполнения каждой 16-й ноты в зависимости от темпа, который обычно составляет 100-150 миллисекунд. Функция, которую он выполняет, проверяет, есть ли заметка, которая должна быть проверена на нажатия клавиш пользователя.

Но я читал о том, как setInterval может страдать от дрейфа и может быть не очень точным. Для песни, которая длится 3-4 минуты и нуждается в точности 100 мс (если механика синхронизации даже немного выключена, это может очень расстраивать для пользователей), похоже, что это не может быть самым большим решением.

Так есть ли более конкретная альтернатива? T

  • 0
    can suffer from drift - я читал это утверждение раньше и решил проверить это утверждение, и обнаружил, по крайней мере в Firefox, что дрейфа как такового нет, есть джиттер
  • 0
    Вы должны запрашивать информацию на основе взаимодействия с пользователем, а не setInterval.
Показать ещё 2 комментария
Теги:
web

4 ответа

1
Лучший ответ

Вероятно, было бы лучшей идеей рассчитать все в абсолютном времени. Итак, у меня есть var starttime = Date.now(); , а затем вычислить, где каждая нота должна быть var expected_note_time = starttime+beat_interval*beat_number. Затем вы можете добавить слушателя при нажатии клавиши, а затем записать точное время нажатия клавиши. Если abs(time_pressed-expected_note_time) < ALLOWED_MISTAKE_VARIANCE, затем добавьте эту точку в счет пользователя. Удачи.

  • 0
    У меня действительно есть точное решение для проверки пользовательского ввода. Тем не менее, другой способ работы игры заключается в том, что даже если пользователь ничего не делает для всей игры, игре все равно необходимо проверять каждую ноту в нужное время, чтобы уменьшить количество баллов, если пользователь ничего не нажимает.
  • 0
    @AndrewHarris ссылается на этот QA - stackoverflow.com/questions/29971898/… . При этом вы можете использовать setInterval и «макияж» для любого дрожания или дрейфа.
Показать ещё 1 комментарий
0

и нуждается в точности 100 мс

Функция setInterval() будет дрейфовать из-за того, как построен javascript (цикл событий), и если вы заблокируете его с тяжелой задачей с интенсивным процессором, он будет задерживаться. Тем не менее, дрифт будет очень малым (меньше, чем мс), если вы сделаете это правильно.

Хорошим способом избежать этого было бы использование нескольких потоков, но это нелегко сделать в JavaScript.

0

Согласитесь, у setInterval есть некоторые проблемы, например, не важно, работает ли обратный вызов или нет, и не является гибким.

вы можете реализовать свой собственный метод:

function interval(func, wait, times){
var interv = function(w, t){
    return function(){
        if(typeof t === "undefined" || t-- > 0){
            setTimeout(interv, w);
            try{
                func.call(null);
            }
            catch(e){
                t = 0;
                throw e.toString();
            }
        }
    };
}(wait, times);

setTimeout(interv, wait);
};

эта функция имеет внутреннюю функцию, называемую interv, которая автоматически запускается через setTimeout, внутри interv - это замыкание, которое проверяет время повторения, вызывает обратный вызов и снова вызывает interv через setTimeout. В случае возникновения исключения из вызова обратного вызова прерывание интервала прекращается, и исключение будет выбрано.

вы можете использовать его так:

interval(function(){
    // Code block goes here
}, 1000, 10);

которые выполняют часть кода 5 раз с интервалом или 10 секунд, и вы можете сделать что-то среднее между ними.

0

Вы можете кэшировать тики в начале песни, получить количество тиков с тех пор, посмотреть, существует ли заметка в этой точке.

Возвратите количество миллисекунд с 1970/01/01:

var d = new Date();
var n = d.getTime();

Результатом n может быть: 1502156888172

От: https://www.w3schools.com/jsref/jsref_gettime.asp

Ещё вопросы

Сообщество Overcoder
Наверх
Меню