You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes.
We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc)
Once per frame calling for rendering and tweening to keep things as smooth as possible
Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly.
Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs.
It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans.
Signals to the game program if there is a problem which might be fixed by lowering the desiredFps
Time.desiredFps is the new desired frame rate for your game.
Time.suggestedFps is the suggested frame rate for the game based on system load.
Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on.
Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
Copy file name to clipboardExpand all lines: README.md
+11Lines changed: 11 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -93,6 +93,17 @@ Version 2.1.4 - "Bethal" - in development
93
93
* ScaleManager.documentWidth returns the document width in pixels.
94
94
* ScaleManager.documentHeight returns the document height in pixels.
95
95
* TilemapLayers have been given a decent performance boost on canvas with map shifting edge-redraw (thanks @pnstickne#1250)
96
+
* A large refactor to how the internal game timers and physics calculations has been made. We've now swapped to using a fixed time step internally across Phaser, instead of the variable one we had before that caused glitchse on low-fps systems. Thanks to pjbaron for his help with all of these related changes.
97
+
* We have separated the logic and render updates to permit slow motion and time slicing effects. We've fixed time calling to fix physics problems caused by variable time updates (i.e. collisions sometimes missing, objects tunneling, etc)
98
+
* Once per frame calling for rendering and tweening to keep things as smooth as possible
99
+
* Calculates a `suggestedFps` value (in multiples of 5 fps) based on a 2 second average of actual elapsed time values in the `Time.update` method. This is recalculated every 2 seconds so it could be used on a level-by-level basis if a game varies dramatically. I.e. if the fps rate consistently drops, you can adjust your game effects accordingly.
100
+
* Game loop now tries to "catch up" frames if it is falling behind by iterating the logic update. This will help if the logic is occasionally causing things to run too slow, or if the renderer occasionally pushes the combined frame time over the FPS time. It's not a band-aid for a game that floods a low powered device however, so you still need to code accordingly. But it should help capture issues such as gc spikes or temporarily overloaded CPUs.
101
+
* It now detects 'spiralling' which happens if a lot of frames are pushed out in succession meaning the CPU can never "catch up". It skips frames instead of trying to catch them up in this case. Note: the time value passed to the logic update functions is always constant regardless of these shenanigans.
102
+
* Signals to the game program if there is a problem which might be fixed by lowering the desiredFps
103
+
* Time.desiredFps is the new desired frame rate for your game.
104
+
* Time.suggestedFps is the suggested frame rate for the game based on system load.
105
+
* Time.slowMotion allows you to push the game into a slow motion mode. The default value is 1.0. 2.0 would be half speed, and so on.
106
+
* Time.timeCap is no longer used and now deprecated. All timing is now handled by the fixed time-step code we've introduced.
Copy file name to clipboardExpand all lines: src/time/Time.js
+64-20Lines changed: 64 additions & 20 deletions
Original file line number
Diff line number
Diff line change
@@ -21,6 +21,7 @@ Phaser.Time = function (game) {
21
21
22
22
/**
23
23
* @property {number} time - Game time counter. If you need a value for in-game calculation please use Phaser.Time.now instead.
24
+
* - This always contains Date.now, but Phaser.Time.now will hold the high resolution RAF timer value (if RAF is available)
24
25
* @protected
25
26
*/
26
27
this.time=0;
@@ -49,6 +50,35 @@ Phaser.Time = function (game) {
49
50
*/
50
51
this.pausedTime=0;
51
52
53
+
/**
54
+
* @property {number} desiredFps = 60 - The desired frame-rate for this project.
55
+
*/
56
+
this.desiredFps=60;
57
+
58
+
/**
59
+
* @property {number} suggestedFps = null - The suggested frame-rate for this project.
60
+
* NOTE: not available until after a few frames have passed, it is recommended to use this after a few seconds (eg. after the menus)
61
+
*/
62
+
this.suggestedFps=null;
63
+
64
+
/**
65
+
* @property {number} _frameCount - count the number of calls to time.update since the last suggestedFps was calculated
66
+
* @private
67
+
*/
68
+
this._frameCount=0;
69
+
70
+
/**
71
+
* @property {number} _elapsedAcumulator - sum of the elapsed time since the last suggestedFps was calculated
72
+
* @private
73
+
*/
74
+
this._elapsedAccumulator=0;
75
+
76
+
/**
77
+
* @property {number} slowMotion = 1.0 - Scaling factor to make the game move smoothly in slow motion (1.0 = normal speed, 2.0 = half speed)
78
+
* @type {Number}
79
+
*/
80
+
this.slowMotion=1.0;
81
+
52
82
/**
53
83
* @property {boolean} advancedTiming - If true Phaser.Time will perform advanced profiling including the fps rate, fps min/max and msMin and msMax.
54
84
* @default
@@ -93,9 +123,12 @@ Phaser.Time = function (game) {
93
123
this.deltaCap=0;
94
124
95
125
/**
96
-
* @property {number} timeCap - If the difference in time between two frame updates exceeds this value, the frame time is reset to avoid huge elapsed counts.
126
+
* @property {number} timeCap - If the difference in time between two frame updates exceeds this value in ms, the frame time is reset to avoid huge elapsed counts.
127
+
* - assumes a desiredFps of 60
128
+
*
129
+
* DEPRECATED: this no longer has any effect since the change to fixed-time stepping in game.update 3rd November 2014
97
130
*/
98
-
this.timeCap=1/60*1000;
131
+
this.timeCap=1000/60;
99
132
100
133
/**
101
134
* @property {number} frames - The number of frames record in the last second. Only calculated if Time.advancedTiming is true.
@@ -113,9 +146,9 @@ Phaser.Time = function (game) {
113
146
this.timeToCall=0;
114
147
115
148
/**
116
-
* @property {number} lastTime - Internal value used by timeToCall as part of the setTimeout loop
149
+
* @property {number} timeExpected - The time when the next call is expected when using setTimer to control the update loop
117
150
*/
118
-
this.lastTime=0;
151
+
this.timeExpected=0;
119
152
120
153
/**
121
154
* @property {Phaser.Timer} events - This is a Phaser.Timer object bound to the master clock to which you can add timed events.
@@ -242,25 +275,39 @@ Phaser.Time.prototype = {
242
275
*/
243
276
update: function(time){
244
277
278
+
// this.time always holds Date.now, this.now may hold the RAF high resolution time value if RAF is available (otherwise it also holds Date.now)
279
+
this.time=Date.now();
280
+
281
+
// 'now' is currently still holding the time of the last call, move it into prevTime
0 commit comments