1
\$\begingroup\$

So i have the game logic and render in the callback for requestAnimationFrame, and somehow the ticks run very weird.

In fact, the rendering happens alright. But the ticks seem to skip an if, to be specific.

The questionable code moves the entity a few pixels until an amount of pixels is traveled.

When the tab isn't viewed the movement happens, and gets rendered correctly, but when going back to the tab i see that the movement went way to far and to make it more dubious, the entity travels back to its actual target position.

It feels a bit like the frames get rendered with the tick-function using kind of a state, like the variables keep the same value while the tab isn't viewed, and when viewing the tab again all the frames get played back reverse until the movement should actually stop.

Is there any reason for this and maybe a solution, too?

\$\endgroup\$
2
\$\begingroup\$

Indeed, that's one of the "features" of requestAnimationFrame, it frees resources from not-focused tabs.

To use this animation method you should use deltatime to keep track of the time elapsed between frames so you can adapt your movement and calculations to that span.

int last;
int now = Date.now();
int elapsed = 0;

function Draw() {
  last = now;
  now = Date.now();
  elapsed = now - last;

  my_player.moveX(speed * elapsed);
  requestAnimationFrame(Draw);
}
Draw();

In this case, as you see, the player will move the same distance per second even if you are in other tab cause the real calculation will be done with the time elapsed between ticks instead of using the amount of ticks

\$\endgroup\$
  • \$\begingroup\$ Oh damn, im using deltas, just not there because im in testing as of now. So the deltas correspond to extremely small values (or even 0) then and so the right movements happen, did I get this right? ~ gonna accept if i get a yes from you, thanks a lot! \$\endgroup\$ – nitwhiz Apr 27 '17 at 11:35
  • \$\begingroup\$ Well, in C you have chrono time, it's much more precise than Date.now() so there's no way to get 0 as deltatime, but in this case you could calculate yor movement by using mov = speed * ((deltatime/100) + 1) for example (check this, i wrote it without any test), the idea is that base movement is the speed (it's a new tick, so this is the minimum movement) and it's multiplied by the theoric ticks elapsed. \$\endgroup\$ – PRDeving Apr 27 '17 at 11:44
  • \$\begingroup\$ Yeah exactly, thats what I meant. Thanks for all the details. \$\endgroup\$ – nitwhiz Apr 27 '17 at 11:46
  • \$\begingroup\$ Anyways, if the delta is too small, probably it's not time to render again yet, you should pick a FPS and stick to that frame rate, remember that each repaint means CPU load, keep it low and your game will feel smoothy, going over 60 FPS doesn't make sense since screens cant (usually) render over 60Hz and your extra frames per second will be ignored or cached at the best... \$\endgroup\$ – PRDeving Apr 27 '17 at 11:47
  • \$\begingroup\$ The minimum delta when the tab is showed is around 16-ish. With no logic, just a simple Image rendered. I guess animationFrame will 1) limit the framrate anyways and 2) knows when to repaint? \$\endgroup\$ – nitwhiz Apr 27 '17 at 11:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.