我正在构建类似于“吉他英雄”的浏览器游戏。它的工作方式是setInterval设置为每16个音符执行一次,具体取决于速度,通常为100-150毫秒。它执行的功能只是检查是否需要根据用户的按键检查一个音符。
但我一直在阅读有关setInterval如何受到漂移的影响并且可能不太准确。对于一首持续3-4分钟并且需要100ms精度的歌曲(如果定时机制稍微偏离,对用户而言可能非常令人沮丧),似乎它可能不是最好的解决方案。
那么还有一种更精确的选择吗? Ť
答案 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
答案 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中并不容易实现。