Added State Clock and TimerEvents

This commit is contained in:
Richard Davey 2017-06-28 17:17:54 +01:00
parent 8952c1d578
commit 6ac524e3bb
6 changed files with 217 additions and 79 deletions

View file

@ -1,4 +1,4 @@
var CHECKSUM = { var CHECKSUM = {
build: '319d5420-5bd7-11e7-bbe2-93fbaa8629f2' build: '55684a60-5c1b-11e7-8400-af0272f167c9'
}; };
module.exports = CHECKSUM; module.exports = CHECKSUM;

View file

@ -1,5 +1,6 @@
var CameraManager = require('./systems/CameraManager'); var CameraManager = require('./systems/CameraManager');
var Clock = require('../time/Clock');
var Component = require('../components'); var Component = require('../components');
var EventDispatcher = require('../events/EventDispatcher'); var EventDispatcher = require('../events/EventDispatcher');
var GameObjectCreator = require('./systems/GameObjectCreator'); var GameObjectCreator = require('./systems/GameObjectCreator');
@ -8,8 +9,8 @@ var Loader = require('./systems/Loader');
var Settings = require('./Settings'); var Settings = require('./Settings');
var StableSort = require('../utils/array/StableSort'); var StableSort = require('../utils/array/StableSort');
var StateManager = require('./systems/StateManager'); var StateManager = require('./systems/StateManager');
var UpdateManager = require('./systems/UpdateManager');
var TweenManager = require('../tween/TweenManager'); var TweenManager = require('../tween/TweenManager');
var UpdateManager = require('./systems/UpdateManager');
var Systems = function (state, config) var Systems = function (state, config)
{ {
@ -42,6 +43,7 @@ var Systems = function (state, config)
// Reference to State specific managers (Factory, Tweens, Loader, Physics, etc) // Reference to State specific managers (Factory, Tweens, Loader, Physics, etc)
this.add; this.add;
this.cameras; this.cameras;
this.time;
this.events; this.events;
this.load; this.load;
this.make; this.make;
@ -83,6 +85,7 @@ Systems.prototype = {
this.add = new GameObjectFactory(this.state); this.add = new GameObjectFactory(this.state);
this.cameras = new CameraManager(this.state); this.cameras = new CameraManager(this.state);
this.time = new Clock(this.state);
this.events = new EventDispatcher(); this.events = new EventDispatcher();
this.load = new Loader(this.state); this.load = new Loader(this.state);
this.make = new GameObjectCreator(this.state); this.make = new GameObjectCreator(this.state);
@ -105,12 +108,13 @@ Systems.prototype = {
this.state.textures = this.textures; this.state.textures = this.textures;
this.state.add = this.add; this.state.add = this.add;
this.state.make = this.make;
this.state.cameras = this.cameras; this.state.cameras = this.cameras;
this.state.events = this.events; this.state.events = this.events;
this.state.load = this.load; this.state.load = this.load;
this.state.make = this.make;
this.state.settings = this.settings; this.state.settings = this.settings;
this.state.state = this.stateManager; this.state.state = this.stateManager;
this.state.time = this.time;
this.state.tweens = this.tweens; this.state.tweens = this.tweens;
this.state.children = this.children; this.state.children = this.children;
@ -120,6 +124,8 @@ Systems.prototype = {
step: function (time, delta) step: function (time, delta)
{ {
this.time.begin(time);
this.tweens.begin(time); this.tweens.begin(time);
var list = this.children.list; var list = this.children.list;
@ -129,6 +135,8 @@ Systems.prototype = {
list[i].preUpdate(time, delta); list[i].preUpdate(time, delta);
} }
this.time.update(time, delta);
this.tweens.update(time, delta); this.tweens.update(time, delta);
this.cameras.update(time, delta); this.cameras.update(time, delta);
@ -136,29 +144,6 @@ Systems.prototype = {
this.state.update.call(this.state, time, delta); this.state.update.call(this.state, time, delta);
}, },
// Called just once per frame, regardless of speed
/*
begin: function (timestamp, frameDelta)
{
var list = this.children.list;
for (var i = 0; i < list.length; i++)
{
list[i].preUpdate(timestamp, frameDelta);
}
},
// Potentially called multiple times per frame (on super-fast systems)
update: function (timestep, physicsStep)
{
this.cameras.update(timestep);
this.state.update.call(this.state, timestep, physicsStep);
},
*/
// Called just once per frame
render: function (interpolation, renderer) render: function (interpolation, renderer)
{ {
if (!this.settings.visible) if (!this.settings.visible)

128
v3/src/time/Clock.js Normal file
View file

@ -0,0 +1,128 @@
var TimerEvent = require('./TimerEvent');
// There is only ever one instance of a MasterClock per game, and it belongs to the Game.
var Clock = function (state, masterclock)
{
this.state = state;
/**
* The `performance.now()` value when the time was last updated.
* @property {float} time
* @protected
*/
this.time = 0;
/**
* The `now` when the previous update occurred.
* @property {float} prevTime
* @protected
*/
this.prevTime = 0;
/**
* 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._pendingInsertion = [];
this._active = [];
this._pendingRemoval = [];
};
Clock.prototype = {
addEvent: function (config)
{
var event = new TimerEvent(config);
this._pendingInsertion.push(event);
return event;
},
delayedCall: function (delay, callback, args, callbackScope)
{
return this.addEvent({ delay: delay, callback: callback, args: args, callbackScope: callbackScope });
},
begin: function (time)
{
// Delete old events
for (var i = 0; i < this._pendingRemoval.length; i++)
{
var index = this._active.indexOf(this._pendingRemoval[i]);
if (index > -1)
{
this._active.splice(index, 1);
}
}
// Move pending events to the active list
this._active = this._active.concat(this._pendingInsertion.splice(0));
// Clear the lists
this._pendingRemoval.length = 0;
this._pendingInsertion.length = 0;
},
update: function (time, delta)
{
this.prevTime = this.time;
this.time = time;
this.elapsed = time - this.prevTime;
if (this._active.length)
{
this.processEvents(time, this.elapsed);
}
},
processEvents: function (time, elapsed)
{
for (var i = 0; i < this._active.length; i++)
{
var event = this._active[i];
event.elapsed += elapsed;
// console.log(event.elapsed);
if (event.elapsed >= event.delay)
{
var remainder = event.elapsed - event.delay;
// Limit it, in case it's checked in the callback
event.elapsed = event.delay;
// Process the event
event.callback.apply(event.callbackScope, event.args);
if (event.loop || event.repeatCount > 0)
{
event.repeatCount--;
event.elapsed = remainder;
}
else
{
this._pendingRemoval.push(event);
}
}
}
}
};
Clock.prototype.constructor = Clock;
module.exports = Clock;

View file

@ -1,53 +0,0 @@
// There is only ever one instance of a MasterClock per game, and it belongs to the Game.
var MasterClock = function (game)
{
this.game = game;
/**
* The `performance.now()` value when the time was last updated.
* @property {float} time
* @protected
*/
this.time = 0;
/**
* The `now` when the previous update occurred.
* @property {float} prevTime
* @protected
*/
this.prevTime = 0;
/**
* 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 Lazer.Timer#physicsTime physicsTime} as a basis of game/logic calculations instead.
*
* @property {number} elapsed
* @see Lazer.Time.time
* @protected
*/
this.elapsed = 0;
};
MasterClock.prototype.constructor = MasterClock;
MasterClock.prototype = {
step: function (timestamp)
{
this.prevTime = this.time;
this.time = timestamp;
}
};
module.exports = MasterClock;

70
v3/src/time/TimerEvent.js Normal file
View file

@ -0,0 +1,70 @@
var GetValue = require('../utils/object/GetValue');
/**
* 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);
/**
* @property {number} repeatCount - If this TimerEvent repeats it will do so this many times.
*/
this.repeatCount = GetValue(config, 'repeat', 0);
/**
* @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.due = 0;
this.elapsed = 0;
};
TimerEvent.prototype = {
getProgress: function ()
{
return (this.elapsed / this.delay);
}
};
TimerEvent.prototype.constructor = TimerEvent;
module.exports = TimerEvent;

8
v3/src/time/index.js Normal file
View file

@ -0,0 +1,8 @@
// Phaser.Time
module.exports = {
Clock: require('./Clock'),
TimerEvent: require('./TimerEvent')
};