2
\$\begingroup\$

I have just started learning Phaser 3 and making a simple idle game, where you would gain x resources per second. What is the best/recommended way to do something like this?

The two main ways I have found so far are:

delayedCall - this.time.delayedCall(1000, onEvent, null, this);

addEvent - this.time.addEvent({ delay: 1000, callback: onEvent, callbackScope: this });

But I read that Phaser update/rendering is in lockstep and runs at 60fps. So if the game were to drop in FPS, then other things like movement, physics etc. would slow down, but would the timers still fire every second? ie you could end up gaining more resources then you should have as the game is running.

Would it not be better to do a modulus 60 frame count, and invoke any per second logic in that manner?

\$\endgroup\$
3
\$\begingroup\$

In your scene's update method you receive both the current timestamp, and the delta since the last update call (see https://photonstorm.github.io/phaser3-docs/Phaser.Scene.html#update__anchor)

You could use the delta to keep track of the amount of time that has actually passed between frames. As soon as the total exceeds 1 second, subtract a second from the total and add the resources.

Even if a single update takes multiple seconds due to the user's CPU being very busy, switching tabs, or other worst case scenarios, you could still allocate the correct amount of resources as your timer will be say 2304 ms and you can run your resource update function multiple times, subtracting a second from the timer for each call.

this.resources = 0;
this.timer = 0;

update(time, delta) {
    this.timer += delta;
    while (this.timer > 1000) {
        this.resources += 1;
        this.timer -= 1000;
    }

    // Rest of your update loop.
}
\$\endgroup\$
3
  • \$\begingroup\$ Thanks, I think this makes sense. I have read a bit about the ARF and how the game loop works, so it sounds like this solution should work well for slow and fast cases. Would you recommend this approach for an in game timer too? Accumulate the delta on a separate variable (and translate in to seconds, minutes etc.) \$\endgroup\$ – lozzajp May 29 '20 at 15:09
  • \$\begingroup\$ Since, if I my thinking is correct: counting update frames is no good as they won't always be 60fps. In your scenario we might only get one update call in the space of 2304ms. So doing the frame count % 60 will be way off. However checking against the delta is going to be correct? \$\endgroup\$ – lozzajp May 29 '20 at 15:10
  • 1
    \$\begingroup\$ Tying your update logic to frames is never a good approach when relying on RAF (like Phaser does), as for high-refresh rate monitors it will update at a higher rate too, and the whole 75Hz - 240Hz range is commercially available. To get the total game time: the first argument received in the update of your scene gives you a high-resolution timestamp of the current time. You could store the initial value you receive for this in the first update, and on subsequent updates subtract the new time from the initial one. \$\endgroup\$ – vassildador May 30 '20 at 16:12

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.