/** * @author Richard Davey * @copyright 2013 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** * TweenGroup constructor * Create a new TweenGroup. * * @class Phaser.TweenGroup * @constructor * @param {Phaser.Game} game - Current game instance. * @param {number} delay - Delay before this tween will start, defaults to 0 (no delay). * @param {number} repeat - How many time should the TweenGroup repeat itself. Infinity can be used for infinite repetition. * @param {Phaser.Tween} yoyo - Whether this TweenGroup will reverse on completion. * @param {boolean} autoStart - Whether this TweenGroup will start automatically or not. */ Phaser.TweenGroup = function (game, delay, repeat, yoyo, autoStart) { autoStart = autoStart || true; /** * @property {Phaser.Game} game - A reference to the currently running Game. */ this.game = game; /** * @property {number} _duration - Description. * @private * @default */ this._duration = 0; /** * @property {number} _repeat - Description. * @private * @default */ this._repeat = repeat || 0; /** * @property {boolean} _yoyo - Description. * @private * @default */ this._yoyo = yoyo || false; /** * @property {boolean} _reversed - Description. * @private * @default */ this._reversed = false; /** * @property {number} _delayTime - Description. * @private * @default */ this._delayTime = delay || 0; /** * @property {Description} _startTime - Description. * @private * @default null */ this._startTime = null; /** * @property {Description} _onStartCallback - Description. * @private * @default */ this._onStartCallback = null; /** * @property {boolean} _onStartCallbackFired - Description. * @private * @default */ this._onStartCallbackFired = false; /** * @property {Description} _onUpdateCallback - Description. * @private * @default null */ this._onUpdateCallback = null; /** * @property {Description} _onCompleteCallback - Description. * @private * @default null */ this._onCompleteCallback = null; /** * @property {boolean} _paused - Description. * @private * @default false */ this._paused = false; /** * @property {number} _pausedTime - Description. * @private * @default */ this._pausedTime = 0; /** * @property {boolean} pendingDelete - If this TweenGroup is ready to be deleted by the TweenManager. * @default */ this.pendingDelete = false; /** * @property {Phaser.Signal} onStart - Description. */ this.onStart = new Phaser.Signal(); /** * @property {Phaser.Signal} onComplete - Description. */ this.onComplete = new Phaser.Signal(); /** * @property {boolean} isRunning - Description. * @default */ this.isRunning = false; /** * @property {number} _time - Description. * @private */ this._time = 0; /** * @property {array} _tweens - Description. * @private */ this._tweens = []; /** * @property {array} _add - Description. * @private */ this._add = []; /** * @property {boolean} _dirty - Description. * @private */ this._dirty = false; if (autoStart) { this.start(); } }; Phaser.TweenGroup.prototype = { /** * Create and configure a tween that will be added to this group * * @method Phaser.TweenGroup#to * @param {object} object - Object to tween. * @param {object} properties - Properties you want to tween. * @param {number} duration - Duration of this tween. * @param {function} ease - Easing function. * @param {boolean} autoStart - Whether this tween will start automatically or not. * @param {number} delay - Delay before this tween will start, defaults to 0 (no delay). * @param {boolean} repeat - Should the tween automatically restart once complete? (ignores any chained tweens). * @param {Phaser.Tween} yoyo - Description. * @return {Phaser.TweenGroup} Itself. */ to: function ( object, properties, duration, ease, autoStart, delay, repeat, yoyo ) { var tween = new Phaser.Tween(object, this.game); tween.to(properties, duration, ease, autoStart, delay, repeat, yoyo); this.add(tween); return this; }, /** * Starts the TweenGroup. * * @method Phaser.TweenGroup#start * @return {Phaser.TweenGroup} Itself. */ start: function () { this.game.tweens.add(this); this.onStart.dispatch(); this.isRunning = true; this._onStartCallbackFired = false; this._startTime = this.game.time.now + this._delayTime; return this; }, /** * Stops the TweenGroup if running and removes it from the TweenManager. If there are any onComplete callbacks or events they are not dispatched. * * @method Phaser.TweenGroup#stop * @return {Phaser.TweenGroup} Itself. */ stop: function () { this.game.tweens.remove(this); this.isRunning = false; return this; }, /** * Sets a delay time before this tween will start. * * @method Phaser.TweenGroup#delay * @param {number} amount - The amount of the delay in ms. * @return {Phaser.TweenGroup} Itself. */ delay: function ( amount ) { this._delayTime = amount; return this; }, /** * Sets the number of times this tween will repeat. * * @method Phaser.TweenGroup#repeat * @param {number} times - How many times to repeat. * @return {Phaser.TweenGroup} Itself. */ repeat: function ( times ) { this._repeat = times; return this; }, /** * A tween that has yoyo set to true will run through from start to finish, then reverse from finish to start. * Used in combination with repeat you can create endless loops. * * @method Phaser.TweenGroup#yoyo * @param {boolean} yoyo - Set to true to yoyo this tween. * @return {Phaser.TweenGroup} Itself. */ yoyo: function( yoyo ) { this._yoyo = yoyo; return this; }, /** * Sets a callback to be fired when the tween starts. Note: callback will be called in the context of the global scope. * * @method Phaser.TweenGroup#onStartCallback * @param {function} callback - The callback to invoke on start. * @return {Phaser.TweenGroup} Itself. */ onStartCallback: function ( callback ) { this._onStartCallback = callback; return this; }, /** * Sets a callback to be fired each time this tween updates. Note: callback will be called in the context of the global scope. * * @method Phaser.TweenGroup#onUpdateCallback * @param {function} callback - The callback to invoke each time this tween is updated. * @return {Phaser.TweenGroup} Itself. */ onUpdateCallback: function ( callback ) { this._onUpdateCallback = callback; return this; }, /** * Sets a callback to be fired when the tween completes. Note: callback will be called in the context of the global scope. * * @method Phaser.TweenGroup#onCompleteCallback * @param {function} callback - The callback to invoke on completion. * @return {Phaser.TweenGroup} Itself. */ onCompleteCallback: function ( callback ) { this._onCompleteCallback = callback; return this; }, /** * Pauses the tween. * * @method Phaser.TweenGroup#pause */ pause: function () { this._paused = true; this._pausedTime = this.game.time.now; }, /** * Resumes a paused tween. * * @method Phaser.TweenGroup#resume */ resume: function () { this._paused = false; this._startTime += (this.game.time.now - this._pausedTime); }, /** * Core tween update function called by the TweenManager. Does not need to be invoked directly. * * @method Phaser.TweenGroup#update * @param {number} time - A timestamp passed in by the TweenManager. * @return {boolean} false if the tween has completed and should be deleted from the manager, otherwise true (still active). */ update: function ( time ) { var i = 0, numTweens = this._tweens.length, tween = null; var rtime = 0; if ( this._onStartCallbackFired === false ) { if ( this._onStartCallback !== null ) { this._onStartCallback.call(this); } this.onStart.dispatch(this); this._onStartCallbackFired = true; } if ( this._dirty && numTweens > 0) { var max = 0; for (var j = numTweens - 1; j >= 0; j--) { tween = this._tweens[j]; if ( max < ( tween._startTime + tween._duration ) ) { max = tween._startTime + tween._duration; } } this._duration = max; this._dirty = false; } while ( i < numTweens ) { tween = this._tweens[ i ]; if ( ( time < tween._startTime ) || ( time > ( tween._startTime + tween._duration )) || tween._paused) { i++; continue; } rtime = time - tween._startTime; tween.update( rtime ); i++; } if ( this._onUpdateCallback !== null ) { this._onUpdateCallback.call(this); } if ( ( ( time >= this._duration ) && !this._reversed ) || ( ( time <= 0) && this._reversed ) ) { this.onComplete.dispatch(this); if ( this._onCompleteCallback !== null ) { this._onCompleteCallback.call(this); } if ( this._repeat > 0 ) { if ( isFinite( this._repeat ) ) { this._repeat--; } if (this._yoyo) { this._reversed = !this._reversed; } this._startTime = this.game.time.now + this._delayTime; } else { return false; } } if (this._add.length > 0) { this._tweens = this._tweens.concat(this._add); this._add.length = 0; } return true; }, /** * Add a new tween into the TweenGroup. * * @method Phaser.TweenGroup#add * @param {Phaser.Tween} tween - The tween object you want to add. * @returns {Phaser.Tween} The tween object you added to the group. */ add: function ( tween ) { if ( this.isRunning ) { this._add.push( tween ); } else { this._tweens.push( tween ); } tween._startTime = this._duration + tween._delayTime; if ( ( tween._startTime + tween._duration ) > this._duration ) { this._duration = tween._startTime + tween._duration; } this._dirty = true; }, /** * Remove a tween from this TweenGroup. * * @method Phaser.TweenGroup#remove * @param {Phaser.Tween} tween - The tween object you want to remove. */ remove: function ( tween ) { var i = this._tweens.indexOf( tween ); if ( i !== -1 ) { this._tweens[i].pendingDelete = true; } this._dirty = true; } };