Reputation: 57
I am using requestAnimationFrame to make a game (game like a snake), and the frame update speed of the game is initially updated each second one time
It needs to update the "requestAnimationFrame" of this snake from a second each time to 0.5 second each time. Because of many snakes’ design and while a snake touches any item, it will get a speed-up situation for 10 seconds.
My question is how to maintain the main "requestAnimationFrame" (updated every second), and there is still another "requestAnimationFrame" (updated every 0.5 second)?
main requestAnimationFrame code
let speed = 1;
let lastRenderTime = 0;
const doAnimation = function (currentTime) {
window.requestAnimationFrame(doAnimation);
const secondRender = (currentTime - lastRenderTime) / 1000; // secondRender is used to control the update per second
if (secondRender < 1 / speed) {
return;
}
lastRenderTime = currentTime
}
window.requestAnimationFrame(doAnimation);
Upvotes: 0
Views: 225
Reputation: 3130
requestAnimationFrame
fire rate is usually around 60Hz. That is 60 calls per second, giving you a maximum theoretical precision of ~16ms (0.016s).
This means that inside you loop you can make things update at any rate above that. But why would you like to truncate precision?
The whole point of requestAnimationFrame
is to know exactly when a repaint will happen and to pass information about your animation at the right time. As an example: if your snake has to move 1000px every second, why would you notify the browser about the update every second? Ideally you should update your view on every frame. So in this example, a 16px variation every 16ms.
Please see the following snippet and note that there are no conditionals, anywhere. But just continuous update.
Obviously final implementation would depend on your use case, but this is only the working principle.
const boxA = document.getElementById('boxA'); // DEMO
const boxB = document.getElementById('boxB'); // DEMO
let xA = 0; // DEMO
let xB = 0; // DEMO
const speedA = 80; // [px/s]
const speedB = 160; // [px/s]
let then = 0;
const animate = function (now) {
window.requestAnimationFrame(animate);
const delta = (now - then) / 1000;
// A
const a = speedA * delta;
boxA.style.transform = `translateX(${xA += a}px)`; // DEMO
// B
const b = speedB * delta;
boxB.style.transform = `translateX(${xB += b}px)`; // DEMO
then = now
}
window.requestAnimationFrame(animate);
.container {
display: flex;
flex-direction: column;
}
#boxA,
#boxB {
display: inline-block;
height: 50px;
width: 50px;
transform: translateX(0);
}
#boxA {
background-color: #ff0000;
}
#boxB {
background-color: #0000ff;
}
<div class='container'>
<span id='boxA'></span>
<span id='boxB'></span>
</div>
Upvotes: 1
Reputation: 1903
let then, then2;
(function loop(delta) {
then = then || delta;
then2 = then2 || delta;
let time = delta - then;
let time2 = delta - then2;
if (time > 1000) {
then = delta;
// in here every second
}
if (time2 > 500) {
then2 = delta;
// in here every 0.5 seconds
}
document.body.innerHTML = time.toFixed(2) + '<br>' + time2.toFixed(2);
requestAnimationFrame(loop);
})();
Upvotes: 0