mirror of
https://github.com/photonstorm/phaser
synced 2024-11-28 07:31:11 +00:00
Merge pull request #1363 from pnstickne/wip-time-clarify
Time - clarify, Game update expose, and Sprite lifespan update
This commit is contained in:
commit
eec846666a
3 changed files with 118 additions and 52 deletions
|
@ -287,18 +287,29 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant
|
||||||
*/
|
*/
|
||||||
this._codePaused = false;
|
this._codePaused = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of the logic update applied this render frame, starting from 0.
|
||||||
|
*
|
||||||
|
* The first update is `updateNumber === 0` and the last update is `updateNumber === updatesThisFrame.`
|
||||||
|
* @property {number} updateNumber
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
this.updateNumber = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of logic updates expected to occur this render frame;
|
||||||
|
* will be 1 unless there are catch-ups required (and allowed).
|
||||||
|
* @property {integer} updatesThisFrame
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
this.updatesThisFrame = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} _deltaTime - accumulate elapsed time until a logic update is due
|
* @property {number} _deltaTime - accumulate elapsed time until a logic update is due
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
this._deltaTime = 0;
|
this._deltaTime = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {number} count - Update iteration counter.
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.count = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} _lastCount - remember how many 'catch-up' iterations were used on the logicUpdate last frame
|
* @property {number} _lastCount - remember how many 'catch-up' iterations were used on the logicUpdate last frame
|
||||||
* @private
|
* @private
|
||||||
|
@ -312,8 +323,9 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant
|
||||||
this._spiralling = 0;
|
this._spiralling = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {Phaser.Signal} fpsProblemNotifier - if the game is struggling to maintain the desiredFps, this signal will be dispatched
|
* If the game is struggling to maintain the desired FPS, this signal will be dispatched.
|
||||||
* to suggest that the program adjust it's fps closer to the Time.suggestedFps value
|
* The desired/chosen FPS should probably be closer to the {@link Phaser.Time#suggestedFps} value.
|
||||||
|
* @property {Phaser.Signal} fpsProblemNotifier
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
this.fpsProblemNotifier = new Phaser.Signal();
|
this.fpsProblemNotifier = new Phaser.Signal();
|
||||||
|
@ -710,32 +722,39 @@ Phaser.Game.prototype = {
|
||||||
|
|
||||||
// call the game update logic multiple times if necessary to "catch up" with dropped frames
|
// call the game update logic multiple times if necessary to "catch up" with dropped frames
|
||||||
// unless forceSingleUpdate is true
|
// unless forceSingleUpdate is true
|
||||||
this.count = 0;
|
var count = 0;
|
||||||
|
|
||||||
|
this.updatesThisFrame = Math.floor(this._deltaTime / slowStep);
|
||||||
|
if (this.forceSingleUpdate)
|
||||||
|
{
|
||||||
|
this.updatesThisFrame = Math.min(1, this.updatesThisFrame);
|
||||||
|
}
|
||||||
|
|
||||||
while (this._deltaTime >= slowStep)
|
while (this._deltaTime >= slowStep)
|
||||||
{
|
{
|
||||||
this._deltaTime -= slowStep;
|
this._deltaTime -= slowStep;
|
||||||
|
this.updateNumber = count;
|
||||||
this.updateLogic(1.0 / this.time.desiredFps);
|
this.updateLogic(1.0 / this.time.desiredFps);
|
||||||
this.count++;
|
count++;
|
||||||
|
|
||||||
if (this.forceSingleUpdate && this.count === 1)
|
if (this.forceSingleUpdate && count === 1)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// detect spiralling (if the catch-up loop isn't fast enough, the number of iterations will increase constantly)
|
// detect spiralling (if the catch-up loop isn't fast enough, the number of iterations will increase constantly)
|
||||||
if (this.count > this._lastCount)
|
if (count > this._lastCount)
|
||||||
{
|
{
|
||||||
this._spiralling++;
|
this._spiralling++;
|
||||||
}
|
}
|
||||||
else if (this.count < this._lastCount)
|
else if (count < this._lastCount)
|
||||||
{
|
{
|
||||||
// looks like it caught up successfully, reset the spiral alert counter
|
// looks like it caught up successfully, reset the spiral alert counter
|
||||||
this._spiralling = 0;
|
this._spiralling = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._lastCount = this.count;
|
this._lastCount = count;
|
||||||
|
|
||||||
// call the game render update exactly once every frame unless we're playing catch-up from a spiral condition
|
// call the game render update exactly once every frame unless we're playing catch-up from a spiral condition
|
||||||
this.updateRender(this._deltaTime / slowStep);
|
this.updateRender(this._deltaTime / slowStep);
|
||||||
|
|
|
@ -116,9 +116,12 @@ Phaser.Sprite = function (game, x, y, key, frame) {
|
||||||
this.health = 1;
|
this.health = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
|
* To given a Sprite a lifespan, in milliseconds, once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
|
||||||
* The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
|
*
|
||||||
* @property {number} lifespan - The lifespan of the Sprite (in ms) before it will be killed.
|
* The lifespan is decremented by `game.time.physicsElapsed` (converted to milliseconds) each logic update,
|
||||||
|
* and {@link Phaser.Sprite.kill kill} is called once the lifespan reaches 0.
|
||||||
|
*
|
||||||
|
* @property {number} lifespan
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
this.lifespan = 0;
|
this.lifespan = 0;
|
||||||
|
@ -249,7 +252,7 @@ Phaser.Sprite.prototype.preUpdate = function() {
|
||||||
// Only apply lifespan decrement in the first updateLogic pass.
|
// Only apply lifespan decrement in the first updateLogic pass.
|
||||||
if (this.lifespan > 0 && this.game.count === 0)
|
if (this.lifespan > 0 && this.game.count === 0)
|
||||||
{
|
{
|
||||||
this.lifespan -= this.game.time.elapsedMS;
|
this.lifespan -= 1000 * this.game.time.physicsElapsed;
|
||||||
|
|
||||||
if (this.lifespan <= 0)
|
if (this.lifespan <= 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,55 +16,92 @@ Phaser.Time = function (game) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {Phaser.Game} game - Local reference to game.
|
* @property {Phaser.Game} game - Local reference to game.
|
||||||
|
* @protected
|
||||||
*/
|
*/
|
||||||
this.game = game;
|
this.game = game;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} time - This always contains the Date.now value.
|
* The `Date.now()` value when the time was last updated.
|
||||||
|
* @property {integer} time
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
this.time = 0;
|
this.time = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} prevTime - The time the previous update occurred.
|
* The `now` when the previous update occurred.
|
||||||
|
* @property {number} prevTime
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
this.prevTime = 0;
|
this.prevTime = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} now - The high resolution RAF timer value (if RAF is available) or Date.now if using setTimeout.
|
* An increasing value representing cumulative milliseconds since an undisclosed epoch.
|
||||||
|
*
|
||||||
|
* This value must _not_ be used with `Date.now()`.
|
||||||
|
*
|
||||||
|
* The source may either be from a high-res source (eg. if RAF is available) or the standard Date.now;
|
||||||
|
* the value can only be relied upon within a particular game instance.
|
||||||
|
*
|
||||||
|
* @property {number} now
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
this.now = 0;
|
this.now = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} elapsed - Elapsed time since the last frame. In ms if running under setTimeout or an integer if using RAF.
|
* Elapsed time since the last time update, in milliseconds, based on `now`.
|
||||||
|
*
|
||||||
|
* This value _may_ include time that the game is paused/inactive.
|
||||||
|
*
|
||||||
|
* _Note:_ This is updated only once per game loop - even if multiple logic update steps are done.
|
||||||
|
* Use {@link Phaser.Timer#physicsTime physicsTime} as a basis of game/logic calculations instead.
|
||||||
|
*
|
||||||
|
* @property {number} elapsed
|
||||||
* @see Phaser.Time.time
|
* @see Phaser.Time.time
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
this.elapsed = 0;
|
this.elapsed = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} elapsedMS - The time in ms since the last update. Will vary dramatically based on system performance, do not use for physics calculations!
|
* The time in ms since the last time update, in milliseconds, based on `time`.
|
||||||
|
*
|
||||||
|
* This value is corrected for game pauses and will be "about zero" after a game is resumed.
|
||||||
|
*
|
||||||
|
* _Note:_ This is updated once per game loop - even if multiple logic update steps are done.
|
||||||
|
* Use {@link Phaser.Timer#physicsTime physicsTime} as a basis of game/logic calculations instead.
|
||||||
|
*
|
||||||
|
* @property {integer} elapsedMS
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
this.elapsedMS = 0;
|
this.elapsedMS = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} pausedTime - Records how long the game has been paused for. Is reset each time the game pauses.
|
* The physics update delta, in fractional seconds.
|
||||||
* @protected
|
*
|
||||||
|
* This should be used as an applicable multiplier by all logic update steps (eg. `preUpdate/postUpdate/update`)
|
||||||
|
* to ensure consistent game timing.
|
||||||
|
*
|
||||||
|
* With fixed-step updates this normally equivalent to `1.0 / desiredFps`.
|
||||||
|
*
|
||||||
|
* @property {number} physicsElapsed
|
||||||
*/
|
*/
|
||||||
this.pausedTime = 0;
|
this.physicsElapsed = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} desiredFps - The desired frame rate of your game.
|
* The desired frame rate of the game.
|
||||||
|
*
|
||||||
|
* This is used is used to calculate the physic/logic multiplier and how to apply catch-up logic updates.
|
||||||
|
*
|
||||||
|
* @property {number} desiredFps
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
this.desiredFps = 60;
|
this.desiredFps = 60;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} suggestedFps = The suggested frame rate for your game, based on an averaged real frame rate.
|
* The suggested frame rate for your game, based on an averaged real frame rate.
|
||||||
* NOTE: Not available until after a few frames have passed, it is recommended to use this after a few seconds (eg. after the menus)
|
*
|
||||||
|
* _Note:_ This is not available until after a few frames have passed; use it after a few seconds (eg. after the menus)
|
||||||
|
*
|
||||||
|
* @property {number} suggestedFps
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
this.suggestedFps = null;
|
this.suggestedFps = null;
|
||||||
|
@ -109,27 +146,34 @@ Phaser.Time = function (game) {
|
||||||
this.msMax = 0;
|
this.msMax = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} physicsElapsed - The physics motion value as used by Arcade Physics. Equivalent to 1.0 / Time.desiredFps.
|
* The number of render frames record in the last second. Only calculated if Time.advancedTiming is true.
|
||||||
*/
|
* @property {integer} frames
|
||||||
this.physicsElapsed = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {number} frames - The number of frames record in the last second. Only calculated if Time.advancedTiming is true.
|
|
||||||
*/
|
*/
|
||||||
this.frames = 0;
|
this.frames = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} pauseDuration - Records how long the game was paused for in miliseconds.
|
* The `time` when the game was last paused.
|
||||||
|
* @property {number} pausedTime
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
this.pausedTime = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records how long the game was last paused, in miliseconds.
|
||||||
|
* (This is not updated until the game is resumed.)
|
||||||
|
* @property {number} pauseDuration
|
||||||
*/
|
*/
|
||||||
this.pauseDuration = 0;
|
this.pauseDuration = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} timeToCall - The value that setTimeout needs to work out when to next update
|
* @property {number} timeToCall - The value that setTimeout needs to work out when to next update
|
||||||
|
* @protected
|
||||||
*/
|
*/
|
||||||
this.timeToCall = 0;
|
this.timeToCall = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property {number} timeExpected - The time when the next call is expected when using setTimer to control the update loop
|
* @property {number} timeExpected - The time when the next call is expected when using setTimer to control the update loop
|
||||||
|
* @protected
|
||||||
*/
|
*/
|
||||||
this.timeExpected = 0;
|
this.timeExpected = 0;
|
||||||
|
|
||||||
|
@ -272,13 +316,13 @@ Phaser.Time.prototype = {
|
||||||
update: function (time) {
|
update: function (time) {
|
||||||
|
|
||||||
// Set to the old Date.now value
|
// Set to the old Date.now value
|
||||||
this.elapsedMS = this.time;
|
var previousDateNow = this.time;
|
||||||
|
|
||||||
// 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)
|
// 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)
|
||||||
this.time = Date.now();
|
this.time = Date.now();
|
||||||
|
|
||||||
// Adjust accorindlgy.
|
// Adjust accorindlgy.
|
||||||
this.elapsedMS = this.time - this.elapsedMS;
|
this.elapsedMS = this.time - previousDateNow;
|
||||||
|
|
||||||
// 'now' is currently still holding the time of the last call, move it into prevTime
|
// 'now' is currently still holding the time of the last call, move it into prevTime
|
||||||
this.prevTime = this.now;
|
this.prevTime = this.now;
|
||||||
|
|
Loading…
Reference in a new issue