diff --git a/v3/src/checksum.js b/v3/src/checksum.js index d0789a9df..cd644448f 100644 --- a/v3/src/checksum.js +++ b/v3/src/checksum.js @@ -1,4 +1,4 @@ var CHECKSUM = { -build: '319d5420-5bd7-11e7-bbe2-93fbaa8629f2' +build: '55684a60-5c1b-11e7-8400-af0272f167c9' }; module.exports = CHECKSUM; \ No newline at end of file diff --git a/v3/src/state/Systems.js b/v3/src/state/Systems.js index e1ef385db..037e28f47 100644 --- a/v3/src/state/Systems.js +++ b/v3/src/state/Systems.js @@ -1,5 +1,6 @@ var CameraManager = require('./systems/CameraManager'); +var Clock = require('../time/Clock'); var Component = require('../components'); var EventDispatcher = require('../events/EventDispatcher'); var GameObjectCreator = require('./systems/GameObjectCreator'); @@ -8,8 +9,8 @@ var Loader = require('./systems/Loader'); var Settings = require('./Settings'); var StableSort = require('../utils/array/StableSort'); var StateManager = require('./systems/StateManager'); -var UpdateManager = require('./systems/UpdateManager'); var TweenManager = require('../tween/TweenManager'); +var UpdateManager = require('./systems/UpdateManager'); var Systems = function (state, config) { @@ -42,6 +43,7 @@ var Systems = function (state, config) // Reference to State specific managers (Factory, Tweens, Loader, Physics, etc) this.add; this.cameras; + this.time; this.events; this.load; this.make; @@ -83,6 +85,7 @@ Systems.prototype = { this.add = new GameObjectFactory(this.state); this.cameras = new CameraManager(this.state); + this.time = new Clock(this.state); this.events = new EventDispatcher(); this.load = new Loader(this.state); this.make = new GameObjectCreator(this.state); @@ -105,12 +108,13 @@ Systems.prototype = { this.state.textures = this.textures; this.state.add = this.add; - this.state.make = this.make; this.state.cameras = this.cameras; this.state.events = this.events; this.state.load = this.load; + this.state.make = this.make; this.state.settings = this.settings; this.state.state = this.stateManager; + this.state.time = this.time; this.state.tweens = this.tweens; this.state.children = this.children; @@ -120,6 +124,8 @@ Systems.prototype = { step: function (time, delta) { + this.time.begin(time); + this.tweens.begin(time); var list = this.children.list; @@ -129,6 +135,8 @@ Systems.prototype = { list[i].preUpdate(time, delta); } + this.time.update(time, delta); + this.tweens.update(time, delta); this.cameras.update(time, delta); @@ -136,29 +144,6 @@ Systems.prototype = { 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) { if (!this.settings.visible) diff --git a/v3/src/time/Clock.js b/v3/src/time/Clock.js new file mode 100644 index 000000000..d32c51c97 --- /dev/null +++ b/v3/src/time/Clock.js @@ -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; diff --git a/v3/src/time/MasterClock.js b/v3/src/time/MasterClock.js deleted file mode 100644 index b20bf957b..000000000 --- a/v3/src/time/MasterClock.js +++ /dev/null @@ -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; diff --git a/v3/src/time/TimerEvent.js b/v3/src/time/TimerEvent.js new file mode 100644 index 000000000..8eeb24165 --- /dev/null +++ b/v3/src/time/TimerEvent.js @@ -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; diff --git a/v3/src/time/index.js b/v3/src/time/index.js new file mode 100644 index 000000000..5a8246bf0 --- /dev/null +++ b/v3/src/time/index.js @@ -0,0 +1,8 @@ +// Phaser.Time + +module.exports = { + + Clock: require('./Clock'), + TimerEvent: require('./TimerEvent') + +};