mirror of
https://github.com/photonstorm/phaser
synced 2024-11-23 13:13:43 +00:00
Timer class overhaul.
This commit is contained in:
parent
7aa45b5872
commit
aa3a86df6e
4 changed files with 312 additions and 79 deletions
45
examples/wip/timer simple.js
Normal file
45
examples/wip/timer simple.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
|
||||
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
|
||||
|
||||
function preload() {
|
||||
|
||||
game.load.image('mushroom', 'assets/sprites/mushroom2.png');
|
||||
|
||||
}
|
||||
|
||||
var timer;
|
||||
|
||||
function create() {
|
||||
|
||||
game.stage.backgroundColor = '#007236';
|
||||
|
||||
timer = game.time.create(1000, false);
|
||||
|
||||
timer.repeat(1, 10);
|
||||
|
||||
timer.onEvent.add(addSprite, this);
|
||||
|
||||
timer.start();
|
||||
|
||||
// text = game.add.text(0, 0, "Text Above Sprites", { font: "64px Arial", fill: "#00bff3", align: "center" });
|
||||
|
||||
}
|
||||
|
||||
function addSprite() {
|
||||
|
||||
game.add.sprite(game.world.randomX, game.world.randomY, 'mushroom');
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
game.debug.renderText(timer.ms, 32, 32);
|
||||
// game.debug.renderCameraInfo(game.camera, 32, 32);
|
||||
|
||||
}
|
|
@ -118,10 +118,55 @@ Phaser.Time = function (game) {
|
|||
*/
|
||||
this._justResumed = false;
|
||||
|
||||
/**
|
||||
* @property {array} _timers - Internal store of Phaser.Timer objects.
|
||||
* @private
|
||||
*/
|
||||
this._timers = [];
|
||||
|
||||
};
|
||||
|
||||
Phaser.Time.prototype = {
|
||||
|
||||
/**
|
||||
* Creates a new Phaser.Timer object.
|
||||
* @method Phaser.Time#create
|
||||
* @param {number} [timeUnit=1000] - The number of ms that represent 1 unit of time. For example a timer that ticks every second would have a timeUnit value of 1000.
|
||||
* @param {boolean} [autoDestroy=true] - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).
|
||||
* @return {Phaser.Timer} The Timer object that was created.
|
||||
*/
|
||||
create: function (timeUnit, autoDestroy) {
|
||||
|
||||
if (typeof autoDestroy === 'undefined') { autoDestroy = true; }
|
||||
|
||||
var timer = new Phaser.Timer(this.game, timeUnit, autoDestroy);
|
||||
|
||||
if (typeof delay !== 'undefined')
|
||||
{
|
||||
timer.add(delay);
|
||||
}
|
||||
|
||||
this._timers.push(timer);
|
||||
|
||||
return timer;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all Timer objects, regardless of their state.
|
||||
* @method Phaser.Time#removeAll
|
||||
*/
|
||||
removeAll: function () {
|
||||
|
||||
for (var i = 0; i < this._timers.length; i++)
|
||||
{
|
||||
this._timers[i].destroy();
|
||||
}
|
||||
|
||||
this._timers = [];
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the game clock and calculate the fps. This is called automatically by Phaser.Game.
|
||||
* @method Phaser.Time#update
|
||||
|
@ -171,6 +216,23 @@ Phaser.Time.prototype = {
|
|||
this.pausedTime = this.now - this._pauseStarted;
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
var len = this._timers.length;
|
||||
|
||||
while (i < len)
|
||||
{
|
||||
if (this._timers[i].update(this.now))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._timers.splice(i, 1);
|
||||
|
||||
len--;
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,14 +5,21 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Timer constructor.
|
||||
* A Timer is a way to create small re-usable or disposable objects that do nothing but wait for a specific moment in time, and then dispatch an event.
|
||||
* You can add as many events to a Timer as you like, each with their own delays. A Timer uses its own timeUnit, which directly correlates to milliseconds.
|
||||
* For example a Timer with a timeUnit of 250 would fire an event every quarter of a second.
|
||||
*
|
||||
* @class Phaser.Timer
|
||||
* @classdesc A Timer
|
||||
* @classdesc A Timer is a way to create small re-usable or disposable objects that do nothing but wait for a specific moment in time, and then dispatch an event.
|
||||
* @constructor
|
||||
* @param {Phaser.Game} game A reference to the currently running game.
|
||||
* @param {number} [timeUnit=1000] - The number of ms that represent 1 unit of time. For example a timer that ticks every second would have a timeUnit value of 1000.
|
||||
* @param {boolean} [autoDestroy=true] - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).
|
||||
*/
|
||||
Phaser.Timer = function (game) {
|
||||
Phaser.Timer = function (game, timeUnit, autoDestroy) {
|
||||
|
||||
if (typeof timeUnit === 'undefined') { timeUnit = Phaser.Timer.SECOND; }
|
||||
if (typeof autoDestroy === 'undefined') { autoDestroy = true; }
|
||||
|
||||
/**
|
||||
* @property {Phaser.Game} game - Local reference to game.
|
||||
|
@ -20,92 +27,154 @@ Phaser.Timer = function (game) {
|
|||
this.game = game;
|
||||
|
||||
/**
|
||||
* The time at which this Timer instance started.
|
||||
* @property {number} _started
|
||||
* @property {number} _started - The time at which this Timer instance started.
|
||||
* @private
|
||||
* @default
|
||||
*/
|
||||
this._started = 0;
|
||||
|
||||
/**
|
||||
* The time (in ms) that the last second counter ticked over.
|
||||
* @property {number} _timeLastSecond
|
||||
* @private
|
||||
* @property {boolean} running - True if the Timer is actively running.
|
||||
* @default
|
||||
*/
|
||||
this._timeLastSecond = 0;
|
||||
|
||||
this.running = false;
|
||||
|
||||
/**
|
||||
* @property {boolean} pauseWithGame - If true then the timer will update itself automatically if the game pauses, otherwise it will carry on dispatching regardless.
|
||||
* @default
|
||||
*/
|
||||
this.pauseWithGame = true;
|
||||
|
||||
/**
|
||||
* @property {boolean} autoDestroy - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).
|
||||
*/
|
||||
this.autoDestroy = autoDestroy;
|
||||
|
||||
/**
|
||||
* @property {boolean} expired - An expired Timer is one in which all of its events have been dispatched and none are pending.
|
||||
* @default
|
||||
*/
|
||||
this.expired = false;
|
||||
|
||||
/**
|
||||
* @property {array} events - An array holding the event data.
|
||||
*/
|
||||
this.events = [];
|
||||
|
||||
/**
|
||||
* This is the event you should listen for. It will be dispatched whenever one of your events is triggered.
|
||||
* It will pass whatever properties you set-up for the event as parameters.
|
||||
* @property {Phaser.Signal} onEvent
|
||||
*/
|
||||
this.onEvent = new Phaser.Signal();
|
||||
|
||||
// Need to add custom FPS rate, for now we'll just use seconds
|
||||
/**
|
||||
* @property {number} timeUnit - The unit of time being used by this Timer.
|
||||
*/
|
||||
this.timeUnit = timeUnit;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Timer.MINUTE = 60000;
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Timer.SECOND = 1000;
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Timer.HALF = 500;
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {number}
|
||||
*/
|
||||
Phaser.Timer.QUARTER = 250;
|
||||
|
||||
Phaser.Timer.prototype = {
|
||||
|
||||
// delay could be from now, when the timer is created, or relative to an already running timer
|
||||
/**
|
||||
* Creates a new Event on this Timer.
|
||||
* @method Phaser.Timer#_create
|
||||
* @private
|
||||
*/
|
||||
_create: function (delay, loop, repeatCount, args) {
|
||||
|
||||
// add: function (delay, callback, callbackContext) {
|
||||
this.events.push({
|
||||
delay: delay,
|
||||
tick: delay,
|
||||
expired: false,
|
||||
repeatCount: repeatCount,
|
||||
loop: loop,
|
||||
args: args
|
||||
});
|
||||
|
||||
this.expired = false;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a new Event to this Timer. The event will fire after the given amount of 'delay' has passed if the Timer is running.
|
||||
* Call Timer.start() once you have added all of the Events you require for this Timer.
|
||||
* @method Phaser.Timer#add
|
||||
* @param {number} [delay] - The number of timeUnits before the Timer will dispatch its onEvent signal.
|
||||
*/
|
||||
add: function (delay) {
|
||||
|
||||
this.events.push({
|
||||
delay: delay,
|
||||
dispatched: false,
|
||||
repeatCount: 0,
|
||||
loop: false,
|
||||
args: Array.prototype.splice.call(arguments, 1)
|
||||
});
|
||||
|
||||
// this.events.push({
|
||||
// delay: delay,
|
||||
// dispatched: false,
|
||||
// callback: callback,
|
||||
// callbackContext: callbackContext,
|
||||
// args: Array.prototype.splice.call(arguments, 3)
|
||||
// });
|
||||
this._create(delay, false, 0, Array.prototype.splice.call(arguments, 1));
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a new Event to this Timer that will repeat for the given number of iterations.
|
||||
* The event will fire after the given amount of 'delay' has passed if the Timer is running.
|
||||
* Call Timer.start() once you have added all of the Events you require for this Timer.
|
||||
* @method Phaser.Timer#repeat
|
||||
* @param {number} [delay] - The number of timeUnits before the Timer will dispatch its onEvent signal.
|
||||
* @param {number} [count] - The number of times to repeat this Event.
|
||||
*/
|
||||
repeat: function (delay, count) {
|
||||
|
||||
this.events.push({
|
||||
delay: delay,
|
||||
dispatched: false,
|
||||
repeatCount: count,
|
||||
loop: false,
|
||||
args: Array.prototype.splice.call(arguments, 2)
|
||||
});
|
||||
this._create(delay, false, count, Array.prototype.splice.call(arguments, 2));
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a new looped Event to this Timer that will repeat forever or until the Timer is stopped.
|
||||
* The event will fire after the given amount of 'delay' has passed if the Timer is running.
|
||||
* Call Timer.start() once you have added all of the Events you require for this Timer.
|
||||
* @method Phaser.Timer#loop
|
||||
* @param {number} [delay] - The number of timeUnits before the Timer will dispatch its onEvent signal.
|
||||
*/
|
||||
loop: function (delay) {
|
||||
|
||||
this.events.push({
|
||||
delay: delay,
|
||||
dispatched: false,
|
||||
loop: true,
|
||||
args: Array.prototype.splice.call(arguments, 2)
|
||||
});
|
||||
this._create(delay, true, 0, Array.prototype.splice.call(arguments, 1));
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts this Timer running.
|
||||
* @method Phaser.Timer#start
|
||||
*/
|
||||
start: function() {
|
||||
|
||||
this._started = this.game.time.now;
|
||||
this.running = true;
|
||||
|
||||
// sort the events based on delay here, also don't run unless events is populated
|
||||
// add ability to auto-stop once all events are done
|
||||
// add support for maximum duration
|
||||
// add support for delay before starting
|
||||
// add signals?
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops this Timer from running. Does not cause it to be destroyed if autoDestroy is set to true.
|
||||
* @method Phaser.Timer#stop
|
||||
*/
|
||||
stop: function() {
|
||||
|
||||
this.running = false;
|
||||
|
@ -113,46 +182,104 @@ Phaser.Timer.prototype = {
|
|||
|
||||
},
|
||||
|
||||
update: function() {
|
||||
|
||||
// TODO: Game Paused support
|
||||
/**
|
||||
* The main Timer update event.
|
||||
* @method Phaser.Timer#update
|
||||
* @protected
|
||||
* @param {number} time - The time from the core game clock.
|
||||
* @return {boolean} True if there are still events waiting to be dispatched, otherwise false if this Timer can be deleted.
|
||||
*/
|
||||
update: function(time) {
|
||||
|
||||
if (this.running)
|
||||
{
|
||||
var seconds = this.seconds();
|
||||
var now = (time - this._started) / this.timeUnit;
|
||||
var expired = 0;
|
||||
|
||||
for (var i = 0, len = this.events.length; i < len; i++)
|
||||
{
|
||||
if (this.events[i].dispatched === false && seconds >= this.events[i].delay)
|
||||
if (this.events[i].expired === false && now >= this.events[i].tick)
|
||||
{
|
||||
if (this.events[i].loop)
|
||||
{
|
||||
this.events[i].tick += this.events[i].delay - (now - this.events[i].tick);
|
||||
this.onEvent.dispatch.apply(this, this.events[i].args);
|
||||
this.events[i].delay = seconds + this.events[i].delay;
|
||||
}
|
||||
else if (this.events[i].repeatCount > 0)
|
||||
{
|
||||
this.events[i].repeatCount--;
|
||||
this.events[i].tick += this.events[i].delay - (now - this.events[i].tick);
|
||||
this.onEvent.dispatch.apply(this, this.events[i].args);
|
||||
this.events[i].delay = seconds + this.events[i].delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.events[i].dispatched = true;
|
||||
// this.events[i].callback.apply(this.events[i].callbackContext, this.events[i].args);
|
||||
this.events[i].expired = true;
|
||||
this.onEvent.dispatch.apply(this, this.events[i].args);
|
||||
// ought to slice it now
|
||||
}
|
||||
}
|
||||
|
||||
if (this.events[i].expired)
|
||||
{
|
||||
expired++;
|
||||
}
|
||||
}
|
||||
|
||||
// There are no events left at all
|
||||
if (expired === this.events.length)
|
||||
{
|
||||
this.expired = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.expired && this.autoDestroy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
seconds: function() {
|
||||
return (this.game.time.now - this._started) * 0.001;
|
||||
/**
|
||||
* Destroys this Timer. Events are not dispatched.
|
||||
* @method Phaser.Timer#destroy
|
||||
*/
|
||||
destroy: function() {
|
||||
|
||||
this.onEvent.removeAll();
|
||||
this.running = false;
|
||||
this.events = [];
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Phaser.Timer#ms
|
||||
* @property {number} ms - The duration in milliseconds that this Timer has been running for.
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(Phaser.Timer.prototype, "ms", {
|
||||
|
||||
get: function () {
|
||||
return this.game.time.now - this._started;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @name Phaser.Timer#seconds
|
||||
* @property {number} seconds - The duration in seconds that this Timer has been running for.
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(Phaser.Timer.prototype, "seconds", {
|
||||
|
||||
get: function () {
|
||||
return (this.game.time.now - this._started) * 0.001;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Phaser.Timer.prototype.constructor = Phaser.Timer;
|
||||
|
|
|
@ -110,10 +110,9 @@ Phaser.TweenManager.prototype = {
|
|||
|
||||
var i = this._tweens.indexOf(tween);
|
||||
|
||||
if ( i !== -1 ) {
|
||||
|
||||
if (i !== -1)
|
||||
{
|
||||
this._tweens[i].pendingDelete = true;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
@ -134,20 +133,18 @@ Phaser.TweenManager.prototype = {
|
|||
var i = 0;
|
||||
var numTweens = this._tweens.length;
|
||||
|
||||
while ( i < numTweens ) {
|
||||
|
||||
if ( this._tweens[ i ].update( this.game.time.now ) ) {
|
||||
|
||||
while (i < numTweens)
|
||||
{
|
||||
if (this._tweens[i].update(this.game.time.now))
|
||||
{
|
||||
i++;
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
this._tweens.splice(i, 1);
|
||||
|
||||
numTweens--;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If there are any new tweens to be added, do so now - otherwise they can be spliced out of the array before ever running
|
||||
|
@ -183,7 +180,8 @@ Phaser.TweenManager.prototype = {
|
|||
*/
|
||||
pauseAll: function () {
|
||||
|
||||
for (var i = this._tweens.length - 1; i >= 0; i--) {
|
||||
for (var i = this._tweens.length - 1; i >= 0; i--)
|
||||
{
|
||||
this._tweens[i].pause();
|
||||
}
|
||||
|
||||
|
@ -196,7 +194,8 @@ Phaser.TweenManager.prototype = {
|
|||
*/
|
||||
resumeAll: function () {
|
||||
|
||||
for (var i = this._tweens.length - 1; i >= 0; i--) {
|
||||
for (var i = this._tweens.length - 1; i >= 0; i--)
|
||||
{
|
||||
this._tweens[i].resume();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue