phaser/src/animations/Animation.js

933 lines
26 KiB
JavaScript
Raw Normal View History

2018-02-12 16:01:20 +00:00
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2018 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
2018-01-16 13:04:35 +00:00
var Class = require('../utils/Class');
2018-01-16 12:59:05 +00:00
var Frame = require('./AnimationFrame');
2018-01-16 13:04:35 +00:00
var GetValue = require('../utils/object/GetValue');
2018-03-19 16:55:21 +00:00
/**
* @typedef {object} JSONAnimation
*
* @property {string} key - [description]
* @property {string} type - A frame based animation (as opposed to a bone based animation)
* @property {JSONAnimationFrame[]} frames - [description]
* @property {integer} frameRate - The frame rate of playback in frames per second (default 24 if duration is null)
* @property {integer} duration - How long the animation should play for.
* @property {boolean} skipMissedFrames - Skip frames if the time lags, or always advanced anyway?
* @property {integer} delay - Delay before starting playback (in seconds)
* @property {integer} repeat - Number of times to repeat the animation (-1 for infinity)
* @property {integer} repeatDelay - Delay before the repeat starts (in seconds)
* @property {boolean} yoyo - Should the animation yoyo? (reverse back down to the start) before repeating?
* @property {boolean} showOnStart - Should sprite.visible = true when the animation starts to play?
* @property {boolean} hideOnComplete - Should sprite.visible = false when the animation finishes?
*/
/**
* @typedef {object} AnimationFrameConfig
*
* @property {string} key - [description]
2018-03-20 14:58:02 +00:00
* @property {(string|number)} frame - [description]
2018-03-19 16:55:21 +00:00
* @property {float} [duration=0] - [description]
* @property {boolean} [visible] - [description]
* @property {function} [onUpdate] - [description]
*/
/**
2018-03-27 11:30:00 +00:00
* @typedef {object} AnimationConfig
2018-03-19 16:55:21 +00:00
*
* @property {AnimationFrameConfig[]} [frames] - [description]
* @property {string} [defaultTextureKey=null] - [description]
* @property {integer} [frameRate] - The frame rate of playback in frames per second (default 24 if duration is null)
* @property {integer} [duration] - How long the animation should play for.
* @property {boolean} [skipMissedFrames=true] - Skip frames if the time lags, or always advanced anyway?
* @property {integer} [delay=0] - Delay before starting playback (in seconds)
* @property {integer} [repeat=0] - Number of times to repeat the animation (-1 for infinity)
* @property {integer} [repeatDelay=0] - Delay before the repeat starts (in seconds)
* @property {boolean} [yoyo=false] - Should the animation yoyo? (reverse back down to the start) before repeating?
* @property {boolean} [showOnStart=false] - Should sprite.visible = true when the animation starts to play?
* @property {boolean} [hideOnComplete=false] - Should sprite.visible = false when the animation finishes?
2018-03-27 11:30:00 +00:00
* @property {*} [callbackScope] - [description]
* @property {(false|function)} [onStart=false] - [description]
* @property {Array.<*>} [onStartParams] - [description]
* @property {(false|function)} [onRepeat=false] - [description]
* @property {Array.<*>} [onRepeatParams] - [description]
* @property {(false|function)} [onUpdate=false] - [description]
* @property {Array.<*>} [onUpdateParams] - [description]
* @property {(false|function)} [onComplete=false] - [description]
* @property {Array.<*>} [onCompleteParams] - [description]
2018-03-19 16:55:21 +00:00
*/
2018-02-07 15:27:21 +00:00
/**
* @classdesc
* A Frame based Animation.
2018-03-19 12:54:20 +00:00
*
2018-02-07 15:27:21 +00:00
* This consists of a key, some default values (like the frame rate) and a bunch of Frame objects.
2018-03-19 12:54:20 +00:00
*
2018-02-07 15:27:21 +00:00
* The Animation Manager creates these. Game Objects don't own an instance of these directly.
* Game Objects have the Animation Component, which are like playheads to global Animations (these objects)
* So multiple Game Objects can have playheads all pointing to this one Animation instance.
*
* @class Animation
* @memberOf Phaser.Animations
* @constructor
* @since 3.0.0
*
* @param {Phaser.Animations.AnimationManager} manager - [description]
* @param {string} key - [description]
2018-03-19 16:55:21 +00:00
* @param {AnimationConfig} config - [description]
2018-02-07 15:27:21 +00:00
*/
var Animation = new Class({
initialize:
2017-04-04 15:50:28 +00:00
function Animation (manager, key, config)
{
2018-01-21 13:01:38 +00:00
/**
* [description]
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#manager
* @type {Phaser.Animations.AnimationManager}
2018-01-21 13:19:58 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.manager = manager;
2018-01-21 13:01:38 +00:00
/**
* [description]
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#key
* @type {string}
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.key = key;
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* A frame based animation (as opposed to a bone based animation)
2018-01-21 13:01:38 +00:00
*
2018-02-22 01:07:30 +00:00
* @name Phaser.Animations.Animation#type
2018-02-07 15:27:21 +00:00
* @type {string}
2018-01-21 13:01:38 +00:00
* @default frame
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.type = 'frame';
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* Extract all the frame data into the frames array
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#frames
2018-03-19 16:55:21 +00:00
* @type {Phaser.Animations.AnimationFrame[]}
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
2018-01-16 12:59:05 +00:00
this.frames = this.getFrames(
manager.textureManager,
GetValue(config, 'frames', []),
GetValue(config, 'defaultTextureKey', null)
);
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* The frame rate of playback in frames per second (default 24 if duration is null)
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#frameRate
* @type {integer}
2018-01-21 13:01:38 +00:00
* @default 24
2018-01-21 13:19:58 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.frameRate = GetValue(config, 'frameRate', null);
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* How long the animation should play for.
* If frameRate is set it overrides this value otherwise frameRate is derived from duration.
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#duration
* @type {integer}
2018-01-21 13:19:58 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.duration = GetValue(config, 'duration', null);
2017-04-05 00:15:53 +00:00
if (this.duration === null && this.frameRate === null)
{
// No duration or frameRate given, use default frameRate of 24fps
this.frameRate = 24;
this.duration = this.frameRate / this.frames.length;
}
else if (this.duration && this.frameRate === null)
{
// Duration given but no frameRate, so set the frameRate based on duration
// I.e. 12 frames in the animation, duration = 4 (4000 ms)
// So frameRate is 12 / 4 = 3 fps
this.frameRate = this.frames.length / this.duration;
}
else
{
// frameRate given, derive duration from it (even if duration also specified)
// I.e. 15 frames in the animation, frameRate = 30 fps
// So duration is 15 / 30 = 0.5 (half a second)
this.duration = this.frames.length / this.frameRate;
}
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* ms per frame (without including frame specific modifiers)
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#msPerFrame
* @type {integer}
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.msPerFrame = 1000 / this.frameRate;
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* Skip frames if the time lags, or always advanced anyway?
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#skipMissedFrames
* @type {boolean}
2018-01-21 13:01:38 +00:00
* @default false
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.skipMissedFrames = GetValue(config, 'skipMissedFrames', true);
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* Delay before starting playback (in seconds)
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#delay
* @type {integer}
2018-01-21 13:01:38 +00:00
* @default 0
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.delay = GetValue(config, 'delay', 0);
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* Number of times to repeat the animation (-1 for infinity)
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#repeat
* @type {integer}
2018-01-21 13:01:38 +00:00
* @default 0
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.repeat = GetValue(config, 'repeat', 0);
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* Delay before the repeat starts (in seconds)
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#repeatDelay
* @type {integer}
2018-01-21 13:01:38 +00:00
* @default 0
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.repeatDelay = GetValue(config, 'repeatDelay', 0);
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* Should the animation yoyo? (reverse back down to the start) before repeating?
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#yoyo
* @type {boolean}
2018-01-21 13:01:38 +00:00
* @default false
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.yoyo = GetValue(config, 'yoyo', false);
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* Should sprite.visible = true when the animation starts to play?
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#showOnStart
* @type {boolean}
2018-01-21 13:01:38 +00:00
* @default false
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.showOnStart = GetValue(config, 'showOnStart', false);
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* Should sprite.visible = false when the animation finishes?
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#hideOnComplete
* @type {boolean}
2018-01-21 13:01:38 +00:00
* @default false
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.hideOnComplete = GetValue(config, 'hideOnComplete', false);
2018-01-21 13:01:38 +00:00
/**
* [description]
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#callbackScope
2018-03-27 11:30:00 +00:00
* @type {*}
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.callbackScope = GetValue(config, 'callbackScope', this);
2018-01-21 13:01:38 +00:00
/**
* [description]
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#onStart
2018-03-27 11:30:00 +00:00
* @type {(false|function)}
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.onStart = GetValue(config, 'onStart', false);
2018-01-21 13:01:38 +00:00
/**
* [description]
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#onStartParams
2018-03-27 11:30:00 +00:00
* @type {Array.<*>}
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.onStartParams = GetValue(config, 'onStartParams', []);
2018-01-21 13:01:38 +00:00
/**
* [description]
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#onRepeat
2018-03-27 11:30:00 +00:00
* @type {(false|function)}
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.onRepeat = GetValue(config, 'onRepeat', false);
2018-01-21 13:01:38 +00:00
/**
* [description]
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#onRepeatParams
2018-03-27 11:30:00 +00:00
* @type {Array.<*>}
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.onRepeatParams = GetValue(config, 'onRepeatParams', []);
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* Called for EVERY frame of the animation.
* See AnimationFrame.onUpdate for a frame specific callback.
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#onUpdate
2018-03-27 11:30:00 +00:00
* @type {(false|function)}
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.onUpdate = GetValue(config, 'onUpdate', false);
2018-01-21 13:01:38 +00:00
/**
* [description]
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#onUpdateParams
2018-03-27 11:30:00 +00:00
* @type {Array.<*>}
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.onUpdateParams = GetValue(config, 'onUpdateParams', []);
2018-01-21 13:01:38 +00:00
/**
* [description]
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#onComplete
2018-03-27 11:30:00 +00:00
* @type {(false|function)}
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.onComplete = GetValue(config, 'onComplete', false);
2018-01-21 13:01:38 +00:00
/**
* [description]
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#onCompleteParams
2018-03-27 11:30:00 +00:00
* @type {Array.<*>}
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.onCompleteParams = GetValue(config, 'onCompleteParams', []);
2018-01-21 13:01:38 +00:00
/**
2018-02-07 15:27:21 +00:00
* Global pause, effects all Game Objects using this Animation instance
2018-01-21 13:01:38 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Animations.Animation#paused
* @type {boolean}
2018-01-21 13:01:38 +00:00
* @default false
2018-02-07 15:27:21 +00:00
* @since 3.0.0
2018-01-21 13:01:38 +00:00
*/
this.paused = false;
this.manager.on('pauseall', this.pause.bind(this));
this.manager.on('resumeall', this.resume.bind(this));
},
2018-01-16 12:59:05 +00:00
// Add frames to the end of the animation
/**
* [description]
*
* @method Phaser.Animations.Animation#addFrame
* @since 3.0.0
*
2018-03-20 14:58:02 +00:00
* @param {(string|AnimationFrameConfig[])} config - [description]
2018-01-16 12:59:05 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Animations.Animation} This Animation object.
2018-01-16 12:59:05 +00:00
*/
addFrame: function (config)
{
return this.addFrameAt(this.frames.length, config);
},
// Add frame/s into the animation
/**
* [description]
*
* @method Phaser.Animations.Animation#addFrameAt
* @since 3.0.0
*
* @param {integer} index - [description]
2018-03-20 14:58:02 +00:00
* @param {(string|AnimationFrameConfig[])} config - [description]
2018-01-16 12:59:05 +00:00
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Animations.Animation} This Animation object.
2018-01-16 12:59:05 +00:00
*/
addFrameAt: function (index, config)
{
var newFrames = this.getFrames(this.manager.textureManager, config);
if (newFrames.length > 0)
{
if (index === 0)
{
this.frames = newFrames.concat(this.frames);
}
else if (index === this.frames.length)
{
this.frames = this.frames.concat(newFrames);
}
else
{
var pre = this.frames.slice(0, index);
var post = this.frames.slice(index);
this.frames = pre.concat(newFrames, post);
}
this.updateFrameSequence();
}
return this;
},
/**
* [description]
*
* @method Phaser.Animations.Animation#checkFrame
* @since 3.0.0
*
* @param {integer} index - [description]
*
* @return {boolean} [description]
*/
checkFrame: function (index)
{
return (index < this.frames.length);
},
/**
* [description]
*
* @method Phaser.Animations.Animation#completeAnimation
* @since 3.0.0
*
* @param {Phaser.GameObjects.Components.Animation} component - [description]
*/
completeAnimation: function (component)
{
if (this.hideOnComplete)
{
component.parent.visible = false;
}
component.stop(true);
},
/**
* [description]
*
* @method Phaser.Animations.Animation#getFirstTick
* @since 3.0.0
*
* @param {Phaser.GameObjects.Components.Animation} component - [description]
* @param {boolean} [includeDelay=true] - [description]
*/
getFirstTick: function (component, includeDelay)
{
if (includeDelay === undefined) { includeDelay = true; }
// When is the first update due?
component.accumulator = 0;
component.nextTick = component.msPerFrame + component.currentFrame.duration;
if (includeDelay)
{
component.nextTick += (component._delay * 1000);
}
},
/**
* [description]
*
* @method Phaser.Animations.Animation#getFrameAt
* @since 3.0.0
*
* @param {integer} index - [description]
*
* @return {Phaser.Animations.AnimationFrame} [description]
*/
getFrameAt: function (index)
{
return this.frames[index];
},
/**
* [description]
*
* @method Phaser.Animations.Animation#getFrames
* @since 3.0.0
*
2018-03-18 13:43:37 +00:00
* @param {Phaser.Textures.TextureManager} textureManager - [description]
2018-03-20 14:58:02 +00:00
* @param {(string|AnimationFrameConfig[])} frames - [description]
2018-03-19 12:54:20 +00:00
* @param {string} [defaultTextureKey] - [description]
2018-01-16 12:59:05 +00:00
*
* @return {Phaser.Animations.AnimationFrame[]} [description]
*/
getFrames: function (textureManager, frames, defaultTextureKey)
{
var out = [];
var prev;
var animationFrame;
var index = 1;
var i;
var textureKey;
// if frames is a string, we'll get all the frames from the texture manager as if it's a sprite sheet
if (typeof frames === 'string')
{
textureKey = frames;
var texture = textureManager.get(textureKey);
var frameKeys = texture.getFrameNames();
frames = [];
frameKeys.forEach(function (idx, value)
{
frames.push({ key: textureKey, frame: value });
});
}
if (!Array.isArray(frames) || frames.length === 0)
{
return out;
}
for (i = 0; i < frames.length; i++)
{
var item = frames[i];
var key = GetValue(item, 'key', defaultTextureKey);
if (!key)
{
continue;
}
// Could be an integer or a string
2018-01-16 12:59:05 +00:00
var frame = GetValue(item, 'frame', 0);
// The actual texture frame
2018-01-16 12:59:05 +00:00
var textureFrame = textureManager.getFrame(key, frame);
animationFrame = new Frame(key, frame, index, textureFrame);
animationFrame.duration = GetValue(item, 'duration', 0);
animationFrame.onUpdate = GetValue(item, 'onUpdate', null);
animationFrame.isFirst = (!prev);
// The previously created animationFrame
if (prev)
{
prev.nextFrame = animationFrame;
animationFrame.prevFrame = prev;
}
out.push(animationFrame);
prev = animationFrame;
index++;
}
if (out.length > 0)
{
animationFrame.isLast = true;
// Link them end-to-end, so they loop
animationFrame.nextFrame = out[0];
out[0].prevFrame = animationFrame;
// Generate the progress data
var slice = 1 / (out.length - 1);
for (i = 0; i < out.length; i++)
{
out[i].progress = i * slice;
}
}
return out;
},
/**
* [description]
*
* @method Phaser.Animations.Animation#getNextTick
* @since 3.0.0
*
* @param {Phaser.GameObjects.Components.Animation} component - [description]
*/
getNextTick: function (component)
{
// accumulator += delta * _timeScale
// after a large delta surge (perf issue for example) we need to adjust for it here
// When is the next update due?
component.accumulator -= component.nextTick;
component.nextTick = component.msPerFrame + component.currentFrame.duration;
},
/**
* [description]
*
* @method Phaser.Animations.Animation#load
* @since 3.0.0
*
* @param {Phaser.GameObjects.Components.Animation} component - [description]
* @param {integer} startFrame - [description]
*/
load: function (component, startFrame)
{
if (startFrame >= this.frames.length)
{
startFrame = 0;
}
2018-01-16 12:59:05 +00:00
if (component.currentAnim !== this)
{
component.currentAnim = this;
component._timeScale = 1;
component.frameRate = this.frameRate;
component.duration = this.duration;
component.msPerFrame = this.msPerFrame;
component.skipMissedFrames = this.skipMissedFrames;
component._delay = this.delay;
component._repeat = this.repeat;
component._repeatDelay = this.repeatDelay;
component._yoyo = this.yoyo;
component._callbackArgs[1] = this;
component._updateParams = component._callbackArgs.concat(this.onUpdateParams);
}
component.updateFrame(this.frames[startFrame]);
},
/**
* [description]
*
* @method Phaser.Animations.Animation#nextFrame
* @since 3.0.0
*
* @param {Phaser.GameObjects.Components.Animation} component - [description]
*/
nextFrame: function (component)
{
var frame = component.currentFrame;
// TODO: Add frame skip support
if (frame.isLast)
{
// We're at the end of the animation
// Yoyo? (happens before repeat)
if (this.yoyo)
{
component.forward = false;
component.updateFrame(frame.prevFrame);
// Delay for the current frame
this.getNextTick(component);
}
else if (component.repeatCounter > 0)
{
// Repeat (happens before complete)
this.repeatAnimation(component);
}
else
{
this.completeAnimation(component);
}
}
else
{
component.updateFrame(frame.nextFrame);
this.getNextTick(component);
}
},
/**
* [description]
*
* @method Phaser.Animations.Animation#previousFrame
* @since 3.0.0
*
* @param {Phaser.GameObjects.Components.Animation} component - [description]
*/
previousFrame: function (component)
{
var frame = component.currentFrame;
// TODO: Add frame skip support
if (frame.isFirst)
{
// We're at the start of the animation
if (component.repeatCounter > 0)
{
// Repeat (happens before complete)
this.repeatAnimation(component);
}
else
{
this.completeAnimation(component);
}
}
else
{
component.updateFrame(frame.prevFrame);
this.getNextTick(component);
}
},
/**
* [description]
*
* @method Phaser.Animations.Animation#removeFrame
* @since 3.0.0
*
* @param {Phaser.Animations.AnimationFrame} frame - [description]
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Animations.Animation} This Animation object.
2018-01-16 12:59:05 +00:00
*/
removeFrame: function (frame)
{
var index = this.frames.indexOf(frame);
if (index !== -1)
{
this.removeFrameAt(index);
}
return this;
},
/**
* [description]
*
* @method Phaser.Animations.Animation#removeFrameAt
* @since 3.0.0
*
* @param {integer} index - [description]
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Animations.Animation} This Animation object.
2018-01-16 12:59:05 +00:00
*/
removeFrameAt: function (index)
{
this.frames.splice(index, 1);
this.updateFrameSequence();
return this;
},
/**
* [description]
*
* @method Phaser.Animations.Animation#repeatAnimation
* @since 3.0.0
*
* @param {Phaser.GameObjects.Components.Animation} component - [description]
*/
repeatAnimation: function (component)
{
if (component._repeatDelay > 0 && component.pendingRepeat === false)
{
component.pendingRepeat = true;
component.accumulator -= component.nextTick;
component.nextTick += (component._repeatDelay * 1000);
}
else
{
component.repeatCounter--;
component.forward = true;
component.updateFrame(component.currentFrame.nextFrame);
this.getNextTick(component);
component.pendingRepeat = false;
if (this.onRepeat)
{
this.onRepeat.apply(this.callbackScope, component._callbackArgs.concat(this.onRepeatParams));
}
}
},
/**
* [description]
*
* @method Phaser.Animations.Animation#setFrame
* @since 3.0.0
*
* @param {Phaser.GameObjects.Components.Animation} component - [description]
*/
setFrame: function (component)
{
// Work out which frame should be set next on the child, and set it
if (component.forward)
{
this.nextFrame(component);
}
else
{
this.previousFrame(component);
}
},
/**
* [description]
*
* @method Phaser.Animations.Animation#toJSON
* @since 3.0.0
*
2018-03-19 16:55:21 +00:00
* @return {JSONAnimation} [description]
2018-01-16 12:59:05 +00:00
*/
toJSON: function ()
{
var output = {
key: this.key,
type: this.type,
frames: [],
frameRate: this.frameRate,
duration: this.duration,
skipMissedFrames: this.skipMissedFrames,
delay: this.delay,
repeat: this.repeat,
repeatDelay: this.repeatDelay,
yoyo: this.yoyo,
showOnStart: this.showOnStart,
hideOnComplete: this.hideOnComplete
};
this.frames.forEach(function (frame)
{
output.frames.push(frame.toJSON());
});
return output;
},
/**
* [description]
*
* @method Phaser.Animations.Animation#updateFrameSequence
* @since 3.0.0
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Animations.Animation} This Animation object.
2018-01-16 12:59:05 +00:00
*/
updateFrameSequence: function ()
{
var len = this.frames.length;
var slice = 1 / (len - 1);
for (var i = 0; i < len; i++)
{
var frame = this.frames[i];
frame.index = i + 1;
frame.isFirst = false;
frame.isLast = false;
frame.progress = i * slice;
if (i === 0)
{
frame.isFirst = true;
frame.isLast = (len === 1);
frame.prevFrame = this.frames[len - 1];
frame.nextFrame = this.frames[i + 1];
}
else if (i === len - 1)
{
frame.isLast = true;
frame.prevFrame = this.frames[len - 2];
frame.nextFrame = this.frames[0];
}
else if (len > 1)
{
frame.prevFrame = this.frames[i - 1];
frame.nextFrame = this.frames[i + 1];
}
}
return this;
},
/**
* [description]
*
* @method Phaser.Animations.Animation#pause
* @since 3.0.0
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Animations.Animation} This Animation object.
2018-01-16 12:59:05 +00:00
*/
pause: function ()
{
this.paused = true;
2018-01-16 12:59:05 +00:00
return this;
},
2018-01-16 12:59:05 +00:00
/**
* [description]
*
* @method Phaser.Animations.Animation#resume
* @since 3.0.0
*
2018-02-07 15:27:21 +00:00
* @return {Phaser.Animations.Animation} This Animation object.
2018-01-16 12:59:05 +00:00
*/
resume: function ()
{
this.paused = false;
2018-01-16 12:59:05 +00:00
return this;
},
2018-01-16 12:59:05 +00:00
/**
* [description]
*
* @method Phaser.Animations.Animation#destroy
* @since 3.0.0
*/
destroy: function ()
{
2018-01-16 12:59:05 +00:00
// TODO
}
});
module.exports = Animation;