当我需要间隔时间非常精确时,是否有比setInterval更好的解决方案?

时间:2017-08-08 01:45:34

标签: javascript web

我正在构建类似于“吉他英雄”的浏览器游戏。它的工作方式是setInterval设置为每16个音符执行一次,具体取决于速度,通常为100-150毫秒。它执行的功能只是检查是否需要根据用户的按键检查​​一个音符。

但我一直在阅读有关setInterval如何受到漂移的影响并且可能不太准确。对于一首持续3-4分钟并且需要100ms精度的歌曲(如果定时机制稍微偏离,对用户而言可能非常令人沮丧),似乎它可能不是最好的解决方案。

那么还有一种更精确的选择吗? Ť

4 个答案:

答案 0 :(得分:1)

在绝对时间内计算所有内容可能更好。因此,请设置var starttime = Date.now();,然后计算每个音符应为var expected_note_time = starttime+beat_interval*beat_number的位置。然后,您可以在按键上添加一个监听器,然后记录按键被击中的确切时间。如果是abs(time_pressed-expected_note_time) < ALLOWED_MISTAKE_VARIANCE,请将该点添加到用户的分数中。祝你好运。

答案 1 :(得分:0)

您可以在歌曲开头缓存刻度,获取此后的刻度数,查看该点是否存在音符。

返回自1970/01/01以来的毫秒数:

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

n的结果可能是:     1502156888172

来自:https://www.w3schools.com/jsref/jsref_gettime.asp

答案 2 :(得分: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中是一个闭包,它检查重复次数,调用回调并通过setTimeout再次调用interv。如果异常从回调调用中冒出,则间隔调用将停止并且将抛出异常。

你可以像这样使用它:

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

以5秒的间隔或10秒执行一段代码,你可以在两者之间做一些事情。

答案 3 :(得分:0)

  

并且需要100ms精度

由于javascript的构建方式(事件循环),setInterval()函数会漂移,如果用大量CPU密集型任务阻止它,它会延迟。但是,如果正确执行,漂移将非常小(小于1 ms)。

避免这种情况的好方法是使用多个线程,但这在JavaScript中并不容易实现。