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

Use setInterval over requestAnimationFrame in a javascript game

我正在构建一个静态增量/打磨游戏。我制作了一些动画(清除 Lv 后资源下降和弹跳、浮动文本、健康栏、一些项目闪烁等)。这是游戏 -> https://krle997.github.io - 抱歉自我宣传,如果违反规则,我会把 link 放下

今天我发现了 requestAnimationFrame 并决定尝试一下,因为每个人都说它比 setInterval 好得多。与 setInterval 相比,它看起来和感觉起来确实更简洁,而且更易于编码,但又让我头疼:

我不能有我的生命条,其他动画总是设置为 60FPS / 144 FPS(fps 可以在游戏设置中更改)。如果玩家注意力不集中,在另一个选项卡上,这将是一个特别大的问题...

setInterval 也不是最好的解决方案。它锁定为1 fps或其他选项卡时,幸运的是,我用https://github.com/turuslan/HackTimer

修复了这一点。

我应该坚持使用 HackTimer 和 setInterval,还是应该尝试转向 reqestAnimationFrame?我要在一天结束时制作一个视频游戏(针对 PC),所以我想要流畅的健康栏和动画,以及尽可能多的帧数。

今天的电脑这么强大,这些东西还重要吗?

感谢您的任何回复,欢迎大家提出意见,祝您有愉快的一天

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

你没有包含你的逻辑,但看起来你正在通过固定增量更新你的状态以响应每个 timer/RAF 回调。那就是你出错的地方。 :-) 相反,根据自上次更新以来的实际时间来更新您的状态。然后使用 RAF 在 DOM.

中反映已更改的状态

现在,您不关心更新之间是 16.6 毫秒(~60 FPS)还是一整秒;你只是相应地更新。

这是一个示例,每次回调更新计数器的固定数量:

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

该计数器的速度将根据主 UI 线程上发生的其他事情、计时器是否被节流等而有所不同。随着时间的推移,它会逐渐偏离准确的每 1 个倒计时第二.

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

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);
<div id="time"></div>