Reputation:
I'm building a static increment / grinding game. There are some animations that I made (resources faling down and bouncing after a cleared Lv, floating text, health bars, some items flashing, etc). Here is the game -> https://krle997.github.io - sorry for self advertising, if it's against the rules I will put the link down
Today I discovered about requestAnimationFrame and decided to give it a try, since everyones saying it's just plain better than setInterval. It does look and feel a lot cleaner and it's easier to code than setInterval, but gave me another headache:
I can't have my health bar, and other animations always set to 60FPS / 144 FPS (fps can be changed in the game settings). This is especially big problem if player is out of focus, on another tab...
setInterval isn't the very best solution either. It locks to 1 FPS or something when the tab is out of focus, luckily I fixed that with this https://github.com/turuslan/HackTimer
Should I stick with HackTimer and setInterval, or should I try move to reqestAnimationFrame? I'm building a video game (aimed for PC) at the end of the day so, I want smooth health bar and animations, and as much frames as I can have.
Computers are so powerful today, does these things even matter?
Thanks for any reply, every opinion is welcome, have a nice day
Upvotes: 0
Views: 1415
Reputation: 1074295
FPS should be irrelevant. :-) And you shouldn't have to hack timers either (which is good, as there's a reason browsers dial back timer processing in inactive tabs, particularly on mobile).
You haven't included your logic, but it would appear that you're updating your state by a fixed increment in response to each timer/RAF callback. That's where you're going wrong. :-) Instead, update your state based on how long it's actually been since the previous update. Then use RAF to reflect that changed state in the DOM.
Now, you don't care if it's a 16.6ms (~60 FPS) or a full second between updates; you just update accordingly.
Here's an example updating a counter by a fixed amount per callback:
var time = document.getElementById("time");
var counter = 10000;
setInterval(function() {
--counter;
time.innerHTML = String(counter);
}, 1000);
<div id="time"></div>
The speed of that counter will vary depending on other things that are happening on the main UI thread, whether timers are throttled, etc. Over time, it will drift away from accurately counting down by one per second.
Instead, it should be updating the counter based on how long it's been since the last update, in case callbacks are throttled:
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>
Upvotes: 1