Merge pull request #3857 from khaleb85/master

Added reverse animation feature (issue: #3837)
This commit is contained in:
Richard Davey 2018-07-24 13:41:10 +01:00 committed by GitHub
commit 50de14b132
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 145 additions and 21 deletions

View file

@ -536,7 +536,14 @@ var Animation = new Class({
component._yoyo = this.yoyo; component._yoyo = this.yoyo;
} }
component.updateFrame(this.frames[startFrame]); var frame = this.frames[startFrame];
if (startFrame === 0 && !component.forward)
{
frame = this.getLastFrame();
}
component.updateFrame(frame);
}, },
/** /**
@ -578,16 +585,20 @@ var Animation = new Class({
if (component._yoyo) if (component._yoyo)
{ {
component.forward = false; component.forward = false;
this._updateAndGetNextTick(component, frame.prevFrame);
component.updateFrame(frame.prevFrame);
// Delay for the current frame
this.getNextTick(component);
} }
else if (component.repeatCounter > 0) else if (component.repeatCounter > 0)
{ {
// Repeat (happens before complete) // Repeat (happens before complete)
this.repeatAnimation(component);
if (component._reverse && component.forward)
{
component.forward = false;
}
else
{
this.repeatAnimation(component);
}
} }
else else
{ {
@ -596,12 +607,23 @@ var Animation = new Class({
} }
else else
{ {
component.updateFrame(frame.nextFrame); this._updateAndGetNextTick(component, frame.nextFrame);
this.getNextTick(component);
} }
}, },
/**
* Returns the animation last frame.
*
* @method Phaser.Animations.Animation#getLastFrame
* @since 3.12.0
*
* @return {Phaser.Animations.AnimationFrame} component - The Animation Last Frame.
*/
getLastFrame: function ()
{
return this.frames[this.frames.length - 1];
},
/** /**
* [description] * [description]
* *
@ -620,10 +642,24 @@ var Animation = new Class({
{ {
// We're at the start of the animation // We're at the start of the animation
if (component.repeatCounter > 0) if (component._yoyo)
{ {
// Repeat (happens before complete) component.forward = true;
this.repeatAnimation(component); this._updateAndGetNextTick(component, frame.nextFrame);
}
else if (component.repeatCounter > 0)
{
if (component._reverse && !component.forward)
{
component.currentFrame = this.getLastFrame();
this._updateAndGetNextTick(component, component.currentFrame);
}
else
{
// Repeat (happens before complete)
component.forward = true;
this.repeatAnimation(component);
}
} }
else else
{ {
@ -632,12 +668,25 @@ var Animation = new Class({
} }
else else
{ {
component.updateFrame(frame.prevFrame); this._updateAndGetNextTick(component, frame.prevFrame);
this.getNextTick(component);
} }
}, },
/**
* Update Frame and Wait next tick
*
* @method Phaser.Animations.Animation#_updateAndGetNextTick
* @since 3.12.0
*
* @param {Phaser.Animations.AnimationFrame} frame - An Animation frame
*
*/
_updateAndGetNextTick: function (component, frame)
{
component.updateFrame(frame);
this.getNextTick(component);
},
/** /**
* [description] * [description]
* *
@ -705,9 +754,7 @@ var Animation = new Class({
{ {
component.repeatCounter--; component.repeatCounter--;
component.forward = true; component.updateFrame(component.currentFrame[(component.forward) ? 'nextFrame' : 'prevFrame']);
component.updateFrame(component.currentFrame.nextFrame);
if (component.isPlaying) if (component.isPlaying)
{ {

View file

@ -208,7 +208,7 @@ var Animation = new Class({
this._yoyo = false; this._yoyo = false;
/** /**
* Will the playhead move forwards (`true`) or in reverse (`false`) * Will the playhead move forwards (`true`) or in reverse (`false`).
* *
* @name Phaser.GameObjects.Components.Animation#forward * @name Phaser.GameObjects.Components.Animation#forward
* @type {boolean} * @type {boolean}
@ -217,6 +217,17 @@ var Animation = new Class({
*/ */
this.forward = true; this.forward = true;
/**
* An Internal trigger that's play the animation in reverse mode ('true') or not ('false'),
* needed because forward can be changed by yoyo feature.
*
* @name Phaser.GameObjects.Components.Animation#forward
* @type {boolean}
* @default false
* @since 3.12.0
*/
this._reverse = false;
/** /**
* Internal time overflow accumulator. * Internal time overflow accumulator.
* *
@ -496,6 +507,54 @@ var Animation = new Class({
return this.parent; return this.parent;
} }
this.forward = true;
this._reverse = false;
return this._startAnimation(key, startFrame);
},
/**
* Plays an Animation (in reverse mode) on the Game Object that owns this Animation Component.
*
* @method Phaser.GameObjects.Components.Animation#playReverse
* @fires Phaser.GameObjects.Components.Animation#onStartEvent
* @since 3.12.0
*
* @param {string} key - The string-based key of the animation to play, as defined previously in the Animation Manager.
* @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call.
* @param {integer} [startFrame=0] - Optionally start the animation playing from this frame index.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
playReverse: function (key, ignoreIfPlaying, startFrame)
{
if (ignoreIfPlaying === undefined) { ignoreIfPlaying = false; }
if (startFrame === undefined) { startFrame = 0; }
if (ignoreIfPlaying && this.isPlaying && this.currentAnim.key === key)
{
return this.parent;
}
this.forward = false;
this._reverse = true;
return this._startAnimation(key, startFrame);
},
/**
* Load an Animation and fires 'onStartEvent' event,
* extracted from 'play' method
*
* @method Phaser.GameObjects.Components.Animation#_startAnimation
* @fires Phaser.GameObjects.Components.Animation#onStartEvent
* @since 3.12.0
*
* @param {string} key - The string-based key of the animation to play, as defined previously in the Animation Manager.
* @param {integer} [startFrame=0] - Optionally start the animation playing from this frame index.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
_startAnimation: function (key, startFrame)
{
this.load(key, startFrame); this.load(key, startFrame);
var anim = this.currentAnim; var anim = this.currentAnim;
@ -506,7 +565,6 @@ var Animation = new Class({
anim.getFirstTick(this); anim.getFirstTick(this);
this.forward = true;
this.isPlaying = true; this.isPlaying = true;
this.pendingRepeat = false; this.pendingRepeat = false;
@ -520,6 +578,25 @@ var Animation = new Class({
return gameObject; return gameObject;
}, },
/**
* Reverse an Animation that is already playing on the Game Object.
*
* @method Phaser.GameObjects.Components.Animation#reverse
* @since 3.12.0
*
* @param {string} key - The string-based key of the animation to play, as defined previously in the Animation Manager.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
reverse: function (key)
{
if (!this.isPlaying || this.currentAnim.key !== key) { return this.parent; }
this._reverse = !this._reverse;
this.forward = !this.forward;
return this.parent;
},
/** /**
* Returns a value between 0 and 1 indicating how far this animation is through, ignoring repeats and yoyos. * Returns a value between 0 and 1 indicating how far this animation is through, ignoring repeats and yoyos.
* If the animation has a non-zero repeat defined, `getProgress` and `getTotalProgress` will be different * If the animation has a non-zero repeat defined, `getProgress` and `getTotalProgress` will be different