mirror of
https://github.com/photonstorm/phaser
synced 2024-11-26 22:52:14 +00:00
Updated TimerEvent and Clock
Swapped to Class format. Added timeScale, startAt and more robust loop handling.
This commit is contained in:
parent
755fa260c0
commit
5cef085eb5
4 changed files with 167 additions and 120 deletions
|
@ -149,11 +149,25 @@ Game.prototype = {
|
|||
onHidden: function ()
|
||||
{
|
||||
this.loop.pause();
|
||||
|
||||
// var active = this.state.active;
|
||||
|
||||
// for (var i = 0; i < active.length; i++)
|
||||
// {
|
||||
// active[i].state.sys.pause();
|
||||
// }
|
||||
},
|
||||
|
||||
onVisible: function ()
|
||||
{
|
||||
this.loop.resume();
|
||||
|
||||
// var active = this.state.active;
|
||||
|
||||
// for (var i = 0; i < active.length; i++)
|
||||
// {
|
||||
// active[i].state.sys.resume();
|
||||
// }
|
||||
},
|
||||
|
||||
onBlur: function ()
|
||||
|
|
|
@ -135,6 +135,7 @@ Systems.prototype = {
|
|||
list[i].preUpdate(time, delta);
|
||||
}
|
||||
|
||||
// preUpdate TimerEvents
|
||||
this.time.update(time, delta);
|
||||
|
||||
this.tweens.update(time, delta);
|
||||
|
|
|
@ -1,42 +1,22 @@
|
|||
var Class = require('../utils/Class');
|
||||
var TimerEvent = require('./TimerEvent');
|
||||
|
||||
// There is only ever one instance of a MasterClock per game, and it belongs to the Game.
|
||||
var Clock = new Class({
|
||||
|
||||
var Clock = function (state, masterclock)
|
||||
{
|
||||
this.state = state;
|
||||
initialize:
|
||||
|
||||
/**
|
||||
* The `performance.now()` value when the time was last updated.
|
||||
* @property {float} time
|
||||
* @protected
|
||||
*/
|
||||
this.time = 0;
|
||||
function Clock (state)
|
||||
{
|
||||
this.state = state;
|
||||
|
||||
/**
|
||||
* The `now` when the previous update occurred.
|
||||
* @property {float} prevTime
|
||||
* @protected
|
||||
*/
|
||||
this.prevTime = 0;
|
||||
this.now = Date.now();
|
||||
|
||||
/**
|
||||
* Elapsed time since the last time update, in milliseconds, based on `now`.
|
||||
*
|
||||
* This value _may_ include time that the game is paused/inactive.
|
||||
*
|
||||
* @property {number} elapsed
|
||||
* @see Lazer.Time.time
|
||||
* @protected
|
||||
*/
|
||||
this.elapsed = 0;
|
||||
this.paused = false;
|
||||
|
||||
this._pendingInsertion = [];
|
||||
this._active = [];
|
||||
this._pendingRemoval = [];
|
||||
};
|
||||
|
||||
Clock.prototype = {
|
||||
this._active = [];
|
||||
this._pendingInsertion = [];
|
||||
this._pendingRemoval = [];
|
||||
},
|
||||
|
||||
addEvent: function (config)
|
||||
{
|
||||
|
@ -52,10 +32,33 @@ Clock.prototype = {
|
|||
return this.addEvent({ delay: delay, callback: callback, args: args, callbackScope: callbackScope });
|
||||
},
|
||||
|
||||
begin: function (time)
|
||||
clearPendingEvents: function ()
|
||||
{
|
||||
this._pendingInsertion = [];
|
||||
},
|
||||
|
||||
removeAllEvents: function ()
|
||||
{
|
||||
this._pendingRemoval = this._pendingRemoval.concat(this._active);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
begin: function ()
|
||||
{
|
||||
var toRemove = this._pendingRemoval.length;
|
||||
var toInsert = this._pendingInsertion.length;
|
||||
|
||||
if (toRemove === 0 && toInsert === 0)
|
||||
{
|
||||
// Quick bail
|
||||
return;
|
||||
}
|
||||
|
||||
var i;
|
||||
|
||||
// Delete old events
|
||||
for (var i = 0; i < this._pendingRemoval.length; i++)
|
||||
for (i = 0; i < toRemove; i++)
|
||||
{
|
||||
var event = this._pendingRemoval[i];
|
||||
|
||||
|
@ -70,8 +73,17 @@ Clock.prototype = {
|
|||
event.destroy();
|
||||
}
|
||||
|
||||
for (i = 0; i < toInsert; i++)
|
||||
{
|
||||
var event = this._pendingInsertion[i];
|
||||
|
||||
event.elapsed = event.startAt * event.timeScale;
|
||||
|
||||
this._active.push(event);
|
||||
}
|
||||
|
||||
// Move pending events to the active list
|
||||
this._active = this._active.concat(this._pendingInsertion.splice(0));
|
||||
// this._active = this._active.concat(this._pendingInsertion.splice(0));
|
||||
|
||||
// Clear the lists
|
||||
this._pendingRemoval.length = 0;
|
||||
|
@ -80,20 +92,13 @@ Clock.prototype = {
|
|||
|
||||
update: function (time, delta)
|
||||
{
|
||||
this.prevTime = this.time;
|
||||
this.now = time;
|
||||
|
||||
this.time = time;
|
||||
|
||||
this.elapsed = time - this.prevTime;
|
||||
|
||||
if (this._active.length)
|
||||
if (this.paused)
|
||||
{
|
||||
this.processEvents(time, this.elapsed);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
processEvents: function (time, elapsed)
|
||||
{
|
||||
for (var i = 0; i < this._active.length; i++)
|
||||
{
|
||||
var event = this._active[i];
|
||||
|
@ -103,9 +108,11 @@ Clock.prototype = {
|
|||
continue;
|
||||
}
|
||||
|
||||
event.elapsed += elapsed;
|
||||
|
||||
// console.log(event.elapsed);
|
||||
// Use delta time to increase elapsed.
|
||||
// Avoids needing to adjust for pause / resume.
|
||||
// Automatically smoothed by TimeStep class.
|
||||
// In testing accurate to +- 1ms!
|
||||
event.elapsed += delta * event.timeScale;
|
||||
|
||||
if (event.elapsed >= event.delay)
|
||||
{
|
||||
|
@ -115,7 +122,7 @@ Clock.prototype = {
|
|||
event.elapsed = event.delay;
|
||||
|
||||
// Process the event
|
||||
if (!event.hasDispatched)
|
||||
if (!event.hasDispatched && event.callback)
|
||||
{
|
||||
event.hasDispatched = true;
|
||||
event.callback.apply(event.callbackScope, event.args);
|
||||
|
@ -134,10 +141,20 @@ Clock.prototype = {
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function ()
|
||||
{
|
||||
for (var i = 0; i < this._active.length; i++)
|
||||
{
|
||||
this._active[i].destroy();
|
||||
}
|
||||
|
||||
this._active.length = 0;
|
||||
this._pendingRemoval.length = 0;
|
||||
this._pendingInsertion.length = 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Clock.prototype.constructor = Clock;
|
||||
});
|
||||
|
||||
module.exports = Clock;
|
||||
|
|
|
@ -1,85 +1,102 @@
|
|||
var GetValue = require('../utils/object/GetValue');
|
||||
var Class = require('../utils/Class');
|
||||
var GetFastValue = require('../utils/object/GetFastValue');
|
||||
|
||||
/**
|
||||
* A TimerEvent is a single event that is processed by a Phaser.Clock
|
||||
*
|
||||
* It consists of a delay, which is a value in milliseconds after which the event will fire.
|
||||
* When the event fires it calls a specific callback with the specified arguments.
|
||||
*
|
||||
* TimerEvents are removed by their parent timer once finished firing or repeating.
|
||||
*
|
||||
* Use {@link Phaser.Clock#add}, {@link Phaser.Clock#repeat}, or {@link Phaser.Clock#loop} methods to create a new event.
|
||||
*
|
||||
* @class Phaser.TimerEvent
|
||||
* @constructor
|
||||
* @param {number} delay - The delay in ms at which this TimerEvent fires.
|
||||
* @param {number} tick - The tick is the next game clock time that this event will fire at.
|
||||
* @param {number} repeatCount - If this TimerEvent repeats it will do so this many times.
|
||||
* @param {boolean} loop - True if this TimerEvent loops, otherwise false.
|
||||
* @param {function} callback - The callback that will be called when the TimerEvent occurs.
|
||||
* @param {object} callbackContext - The context in which the callback will be called.
|
||||
* @param {any[]} arguments - Additional arguments to be passed to the callback.
|
||||
*/
|
||||
var TimerEvent = function (config)
|
||||
{
|
||||
/**
|
||||
* @property {number} delay - The delay in ms at which this TimerEvent fires.
|
||||
*/
|
||||
this.delay = GetValue(config, 'delay', 0);
|
||||
var TimerEvent = new Class({
|
||||
|
||||
/**
|
||||
* @property {number} repeatCount - If this TimerEvent repeats it will do so this many times.
|
||||
*/
|
||||
this.repeatCount = GetValue(config, 'repeat', 0);
|
||||
initialize:
|
||||
|
||||
/**
|
||||
* @property {boolean} loop - True if this TimerEvent loops, otherwise false.
|
||||
*/
|
||||
this.loop = GetValue(config, 'loop', false);
|
||||
|
||||
/**
|
||||
* @property {function} callback - The callback that will be called when the TimerEvent occurs.
|
||||
*/
|
||||
this.callback = GetValue(config, 'callback', null);
|
||||
|
||||
/**
|
||||
* @property {object} callbackContext - The context in which the callback will be called.
|
||||
*/
|
||||
this.callbackScope = GetValue(config, 'callbackScope', null);
|
||||
|
||||
/**
|
||||
* @property {any[]} arguments - Additional arguments to be passed to the callback.
|
||||
*/
|
||||
this.args = GetValue(config, 'args', []);
|
||||
|
||||
// This works for setting an infinite repeat too
|
||||
if (this.repeatCount === -1)
|
||||
function TimerEvent (config)
|
||||
{
|
||||
this.loop = true;
|
||||
}
|
||||
/**
|
||||
* @property {number} delay - The delay in ms at which this TimerEvent fires.
|
||||
*/
|
||||
this.delay = 0;
|
||||
|
||||
this.elapsed = 0;
|
||||
this.hasDispatched = false;
|
||||
/**
|
||||
* @property {number} repeatCount - If this TimerEvent repeats it will do so this many times.
|
||||
*/
|
||||
this.repeatCount = 0;
|
||||
|
||||
// Swap for a getter / setter
|
||||
this.paused = false;
|
||||
};
|
||||
/**
|
||||
* @property {boolean} loop - True if this TimerEvent loops, otherwise false.
|
||||
*/
|
||||
this.loop = false;
|
||||
|
||||
TimerEvent.prototype = {
|
||||
/**
|
||||
* @property {function} callback - The callback that will be called when the TimerEvent occurs.
|
||||
*/
|
||||
this.callback;
|
||||
|
||||
/**
|
||||
* @property {object} callbackContext - The context in which the callback will be called.
|
||||
*/
|
||||
this.callbackScope;
|
||||
|
||||
/**
|
||||
* @property {any[]} arguments - Additional arguments to be passed to the callback.
|
||||
*/
|
||||
this.args;
|
||||
|
||||
// Scale the time causing this TimerEvent to update
|
||||
this.timeScale = 1;
|
||||
|
||||
// Start this many MS into the elapsed (useful if you want a long duration with repeat, but for the first loop to fire quickly)
|
||||
this.startAt = 0;
|
||||
|
||||
this.elapsed = 0;
|
||||
|
||||
this.paused = false;
|
||||
|
||||
this.hasDispatched = false;
|
||||
|
||||
this.reset(config);
|
||||
},
|
||||
|
||||
reset: function (config)
|
||||
{
|
||||
this.delay = GetFastValue(config, 'delay', 0);
|
||||
|
||||
this.repeatCount = GetFastValue(config, 'repeat', 0);
|
||||
|
||||
this.loop = GetFastValue(config, 'loop', false);
|
||||
|
||||
this.callback = GetFastValue(config, 'callback', undefined);
|
||||
|
||||
this.callbackScope = GetFastValue(config, 'callbackScope', this.callback);
|
||||
|
||||
this.args = GetFastValue(config, 'args', []);
|
||||
|
||||
this.timeScale = GetFastValue(config, 'timeScale', 1);
|
||||
|
||||
this.startAt = GetFastValue(config, 'startAt', 0);
|
||||
|
||||
this.paused = GetFastValue(config, 'paused', false);
|
||||
|
||||
// This works for setting an infinite repeat too
|
||||
if (this.repeatCount === -1)
|
||||
{
|
||||
this.loop = true;
|
||||
}
|
||||
|
||||
this.elapsed = 0;
|
||||
this.hasDispatched = false;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
getProgress: function ()
|
||||
{
|
||||
return (this.elapsed / this.delay);
|
||||
},
|
||||
|
||||
pause: function ()
|
||||
getElapsed: function ()
|
||||
{
|
||||
this.paused = true;
|
||||
return this.elapsed;
|
||||
},
|
||||
|
||||
resume: function ()
|
||||
getElapsedSeconds: function ()
|
||||
{
|
||||
this.paused = false;
|
||||
return this.elapsed * 0.001;
|
||||
},
|
||||
|
||||
remove: function (dispatchCallback)
|
||||
|
@ -102,8 +119,6 @@ TimerEvent.prototype = {
|
|||
this.args.length = 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TimerEvent.prototype.constructor = TimerEvent;
|
||||
});
|
||||
|
||||
module.exports = TimerEvent;
|
||||
|
|
Loading…
Reference in a new issue