I just made a little "Space Invaders" game using plain vanilla Javascript and it's running beautifully on my 2018 MacMini -- but ridiculously and blazingly fast on my 2021 MacBook Pro (which has the M1 chip in it.)
Since I'm using requestAnimationFrame()
for my main animation loop (as opposed to setInerval
), I have full control and went ahead and throttled the animation's frame-rate WAAAY down, literally taking it from 60fps down to 10fps -- but it's STILL running prohibitively fast on the M1 MacBook Pro.
I know my particular M1 MacBook Pro has a screen refresh rate of 120Hz - which might be the biggest culprit and main cause of the problem here, but if so, how do I work around this?
Would appreciate any and all tips and advice.
Thank you.
Yes, requestAnimationFrame()
is indeed a much better option for animation. You just need to take into account the actual time that has passed between two invocations. Then, for example, given speed and delta-time, you can calculate distance.
Here's a very simplistic example, you can find more about "the game loop" or similiar term, online.
var dt, last
var speed = 0.2;
var totalDistance = 0
var maxDistance = 300
function frame(now) {
dt = last ? now - last : 0
update(dt)
render(dt)
last = now;
requestAnimationFrame(frame);
}
function update(dt) {
totalDistance += dt * speed;
if (totalDistance >= maxDistance || totalDistance <= 0) {
speed *= -1
}
totalDistance = Math.max(Math.min(maxDistance, totalDistance), 0)
}
function render(dt) {
element.style.transform = `translateX(${totalDistance}px)`;
}
requestAnimationFrame(frame);
#element {
width: 100px;
height: 100px;
border: 1px solid gray;
}
<div id="element">Hello</div>