在javascript游戏中使用setInterval而不是requestAnimationFrame

时间:2018-04-19 18:04:09

标签: javascript animation setinterval frames requestanimationframe

我正在构建静态增量/磨削游戏。我制作了一些动画(资源缩小并在清除Lv,浮动文本,健康栏,某些项目闪烁之后弹跳等)。这是游戏 - > https://krle997.github.io - 抱歉自我广告,如果违反规则我会将链接放下

今天我发现了requestAnimationFrame,并决定尝试一下,因为每个人都说它比setInterval更好。它看起来和感觉更干净,并且比setInterval更容易编码,但让我头疼:

我无法使用健康栏,其他动画总是设置为60FPS / 144 FPS(fps可以在游戏设置中更改)。如果玩家在另一个标签上失焦,这是一个特别大的问题......

setInterval也不是最好的解决方案。当标签失焦时,它锁定为1 FPS或者其他东西,幸运的是我用https://github.com/turuslan/HackTimer

修复了它

我应该坚持使用HackTimer和setInterval,还是应该尝试移动到reqestAnimationFrame?我在一天结束的时候建立了一个视频游戏(针对PC),所以,我想要平滑的健康栏和动画,以及尽可能多的帧。

今天的计算机如此强大,这些事情是否重要?

感谢您的回复,欢迎每一个意见,祝您有愉快的一天

1 个答案:

答案 0 :(得分:0)

FPS应该是无关紧要的。 :-)你也不应该破解计时器(这很好,因为原因浏览器在非活动标签中拨回计时器处理,特别是在移动设备上)。

您还没有包含您的逻辑,但看起来您会根据每个计时器/ RAF回调以固定的增量更新您的状态。这就是你出错的地方。 :-)而是根据自上次更新以来实际存在的时间来更新您的状态。然后使用RAF反映DOM中的更改状态。

现在,你不在乎它是否是16.6ms(~60 FPS)或更新之间的一整秒;你只需要相应更新。

以下是每个回调按固定金额更新计数器的示例:



var time = document.getElementById("time");
var counter = 10000;
setInterval(function() {
  --counter;
  time.innerHTML = String(counter);
}, 1000);

<div id="time"></div>
&#13;
&#13;
&#13;

该计数器的速度将根据主UI线程上发生的其他事情而变化,无论计时器是否被限制等等。随着时间的推移,它将逐渐减少准确地每秒倒计时一次。

相反,它应该根据自上次更新以来的时间来更新计数器,以防止回调受到限制:

&#13;
&#13;
var time = document.getElementById("time");
var counter = 10000;
var lastUpdate = Date.now();
setInterval(function() {
  var now = Date.now();
  var elapsed = now - lastUpdate;
  lastUpdate = now;
  counter -= elapsed / 1000;
  time.innerHTML = String(Math.floor(counter));
}, 1000);
&#13;
<div id="time"></div>
&#13;
&#13;
&#13;