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-04-04 16:14:43 +00:00
|
|
|
var Clamp = require('../math/Clamp');
|
2018-01-16 13:04:35 +00:00
|
|
|
var Class = require('../utils/Class');
|
2018-12-06 15:28:48 +00:00
|
|
|
var EventEmitter = require('eventemitter3');
|
2018-04-04 16:14:43 +00:00
|
|
|
var FindClosestInSorted = require('../utils/array/FindClosestInSorted');
|
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');
|
2017-04-04 15:32:33 +00:00
|
|
|
|
2018-03-19 16:55:21 +00:00
|
|
|
/**
|
|
|
|
* @typedef {object} JSONAnimation
|
|
|
|
*
|
2018-04-19 15:36:13 +00:00
|
|
|
* @property {string} key - The key that the animation will be associated with. i.e. sprite.animations.play(key)
|
2018-03-19 16:55:21 +00:00
|
|
|
* @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)
|
2018-04-04 15:13:45 +00:00
|
|
|
* @property {integer} duration - How long the animation should play for in milliseconds. If not given its derived from frameRate.
|
2018-03-19 16:55:21 +00:00
|
|
|
* @property {boolean} skipMissedFrames - Skip frames if the time lags, or always advanced anyway?
|
2018-04-04 15:13:45 +00:00
|
|
|
* @property {integer} delay - Delay before starting playback. Value given in milliseconds.
|
2018-03-19 16:55:21 +00:00
|
|
|
* @property {integer} repeat - Number of times to repeat the animation (-1 for infinity)
|
2018-04-04 15:13:45 +00:00
|
|
|
* @property {integer} repeatDelay - Delay before the animation repeats. Value given in milliseconds.
|
2018-03-19 16:55:21 +00:00
|
|
|
* @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
|
|
|
|
*
|
2018-04-19 15:36:13 +00:00
|
|
|
* @property {string} key - The key that the animation will be associated with. i.e. sprite.animations.play(key)
|
2018-03-20 14:58:02 +00:00
|
|
|
* @property {(string|number)} frame - [description]
|
2018-06-26 22:19:14 +00:00
|
|
|
* @property {number} [duration=0] - [description]
|
2018-03-19 16:55:21 +00:00
|
|
|
* @property {boolean} [visible] - [description]
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2018-03-27 11:30:00 +00:00
|
|
|
* @typedef {object} AnimationConfig
|
2018-03-19 16:55:21 +00:00
|
|
|
*
|
2018-04-19 15:36:13 +00:00
|
|
|
* @property {string} [key] - The key that the animation will be associated with. i.e. sprite.animations.play(key)
|
|
|
|
* @property {AnimationFrameConfig[]} [frames] - An object containing data used to generate the frames for the animation
|
|
|
|
* @property {string} [defaultTextureKey=null] - The key of the texture all frames of the animation will use. Can be overridden on a per frame basis.
|
2018-03-19 16:55:21 +00:00
|
|
|
* @property {integer} [frameRate] - The frame rate of playback in frames per second (default 24 if duration is null)
|
2018-04-04 15:13:45 +00:00
|
|
|
* @property {integer} [duration] - How long the animation should play for in milliseconds. If not given its derived from frameRate.
|
2018-03-19 16:55:21 +00:00
|
|
|
* @property {boolean} [skipMissedFrames=true] - Skip frames if the time lags, or always advanced anyway?
|
2018-04-04 15:13:45 +00:00
|
|
|
* @property {integer} [delay=0] - Delay before starting playback. Value given in milliseconds.
|
2018-03-19 16:55:21 +00:00
|
|
|
* @property {integer} [repeat=0] - Number of times to repeat the animation (-1 for infinity)
|
2018-04-04 15:13:45 +00:00
|
|
|
* @property {integer} [repeatDelay=0] - Delay before the animation repeats. Value given in milliseconds.
|
2018-03-19 16:55:21 +00:00
|
|
|
* @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-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
|
2018-10-10 09:49:13 +00:00
|
|
|
* @memberof Phaser.Animations
|
2018-12-06 15:28:48 +00:00
|
|
|
* @extends Phaser.Events.EventEmitter
|
2018-02-07 15:27:21 +00:00
|
|
|
* @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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
var Animation = new Class({
|
2017-04-04 15:32:33 +00:00
|
|
|
|
2018-12-06 15:28:48 +00:00
|
|
|
Extends: EventEmitter,
|
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
initialize:
|
2017-04-04 15:50:28 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
function Animation (manager, key, config)
|
|
|
|
{
|
2018-12-06 15:28:48 +00:00
|
|
|
EventEmitter.call(this);
|
|
|
|
|
2018-01-21 13:01:38 +00:00
|
|
|
/**
|
2018-04-19 15:36:13 +00:00
|
|
|
* A reference to the global Animation Manager
|
2018-01-21 13:01:38 +00:00
|
|
|
*
|
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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.manager = manager;
|
2017-04-12 12:53:55 +00:00
|
|
|
|
2018-01-21 13:01:38 +00:00
|
|
|
/**
|
2018-04-19 15:36:13 +00:00
|
|
|
* The unique identifying string for this animation
|
2018-01-21 13:01:38 +00:00
|
|
|
*
|
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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.key = key;
|
2017-04-04 15:32:33 +00:00
|
|
|
|
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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.type = 'frame';
|
2017-04-04 15:32:33 +00:00
|
|
|
|
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)
|
|
|
|
);
|
2017-04-04 15:32:33 +00:00
|
|
|
|
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
|
|
|
*/
|
2017-07-27 07:22:52 +00:00
|
|
|
this.frameRate = GetValue(config, 'frameRate', null);
|
2017-04-04 15:32:33 +00:00
|
|
|
|
2018-01-21 13:01:38 +00:00
|
|
|
/**
|
2018-04-04 15:13:45 +00:00
|
|
|
* How long the animation should play for, in milliseconds.
|
|
|
|
* If the `frameRate` property has been set then it overrides this value,
|
|
|
|
* otherwise the `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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.duration = GetValue(config, 'duration', null);
|
2017-04-05 00:15:53 +00:00
|
|
|
|
2017-06-30 14:47:51 +00:00
|
|
|
if (this.duration === null && this.frameRate === null)
|
|
|
|
{
|
|
|
|
// No duration or frameRate given, use default frameRate of 24fps
|
|
|
|
this.frameRate = 24;
|
2018-04-04 15:13:45 +00:00
|
|
|
this.duration = (this.frameRate / this.frames.length) * 1000;
|
2017-06-30 14:47:51 +00:00
|
|
|
}
|
|
|
|
else if (this.duration && this.frameRate === null)
|
|
|
|
{
|
|
|
|
// Duration given but no frameRate, so set the frameRate based on duration
|
2018-04-04 15:13:45 +00:00
|
|
|
// I.e. 12 frames in the animation, duration = 4000 ms
|
|
|
|
// So frameRate is 12 / (4000 / 1000) = 3 fps
|
|
|
|
this.frameRate = this.frames.length / (this.duration / 1000);
|
2017-06-30 14:47:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// frameRate given, derive duration from it (even if duration also specified)
|
|
|
|
// I.e. 15 frames in the animation, frameRate = 30 fps
|
2018-04-04 15:13:45 +00:00
|
|
|
// So duration is 15 / 30 = 0.5 * 1000 (half a second, or 500ms)
|
|
|
|
this.duration = (this.frames.length / this.frameRate) * 1000;
|
2017-06-30 14:47:51 +00:00
|
|
|
}
|
2017-04-04 15:32:33 +00:00
|
|
|
|
2018-01-21 13:01:38 +00:00
|
|
|
/**
|
2018-04-04 15:13:45 +00:00
|
|
|
* How many ms per frame, not 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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.msPerFrame = 1000 / this.frameRate;
|
2017-04-04 15:32:33 +00:00
|
|
|
|
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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.skipMissedFrames = GetValue(config, 'skipMissedFrames', true);
|
2017-04-04 15:32:33 +00:00
|
|
|
|
2018-01-21 13:01:38 +00:00
|
|
|
/**
|
2018-04-04 15:13:45 +00:00
|
|
|
* The delay in ms before the playback will begin.
|
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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.delay = GetValue(config, 'delay', 0);
|
2017-04-04 15:32:33 +00:00
|
|
|
|
2018-01-21 13:01:38 +00:00
|
|
|
/**
|
2018-04-04 15:13:45 +00:00
|
|
|
* Number of times to repeat the animation. Set to -1 to repeat forever.
|
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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.repeat = GetValue(config, 'repeat', 0);
|
2017-04-04 15:32:33 +00:00
|
|
|
|
2018-01-21 13:01:38 +00:00
|
|
|
/**
|
2018-04-04 15:13:45 +00:00
|
|
|
* The delay in ms before the a repeat playthrough starts.
|
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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.repeatDelay = GetValue(config, 'repeatDelay', 0);
|
2017-04-10 13:38:44 +00:00
|
|
|
|
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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.yoyo = GetValue(config, 'yoyo', false);
|
2017-04-10 13:38:44 +00:00
|
|
|
|
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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.showOnStart = GetValue(config, 'showOnStart', false);
|
2017-04-10 15:27:32 +00:00
|
|
|
|
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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.hideOnComplete = GetValue(config, 'hideOnComplete', false);
|
2017-04-10 15:27:32 +00:00
|
|
|
|
2018-01-21 13:01:38 +00:00
|
|
|
/**
|
2018-04-04 15:13:45 +00:00
|
|
|
* Global pause. All Game Objects using this Animation instance are impacted by this property.
|
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
|
|
|
*/
|
2017-06-30 14:47:51 +00:00
|
|
|
this.paused = false;
|
2017-04-04 15:32:33 +00:00
|
|
|
|
2018-04-04 16:14:43 +00:00
|
|
|
this.manager.on('pauseall', this.pause, this);
|
|
|
|
this.manager.on('resumeall', this.resume, this);
|
2017-06-30 14:47:51 +00:00
|
|
|
},
|
2017-04-04 15:32:33 +00:00
|
|
|
|
2018-01-16 12:59:05 +00:00
|
|
|
/**
|
2018-04-04 15:13:45 +00:00
|
|
|
* Add frames to the end of the animation.
|
2018-01-16 12:59:05 +00:00
|
|
|
*
|
|
|
|
* @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);
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-04-04 15:13:45 +00:00
|
|
|
* Add frame/s into the animation.
|
2018-01-16 12:59:05 +00:00
|
|
|
*
|
|
|
|
* @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;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-04-04 15:13:45 +00:00
|
|
|
* Check if the given frame index is valid.
|
2018-01-16 12:59:05 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Animations.Animation#checkFrame
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-04-04 15:13:45 +00:00
|
|
|
* @param {integer} index - The index to be checked.
|
2018-01-16 12:59:05 +00:00
|
|
|
*
|
2018-04-04 15:13:45 +00:00
|
|
|
* @return {boolean} `true` if the index is valid, otherwise `false`.
|
2018-01-16 12:59:05 +00:00
|
|
|
*/
|
|
|
|
checkFrame: function (index)
|
|
|
|
{
|
2018-04-04 15:13:45 +00:00
|
|
|
return (index >= 0 && index < this.frames.length);
|
2018-01-16 12:59:05 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Animations.Animation#completeAnimation
|
2018-04-04 15:13:45 +00:00
|
|
|
* @protected
|
2018-01-16 12:59:05 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
|
|
|
* @param {Phaser.GameObjects.Components.Animation} component - [description]
|
|
|
|
*/
|
|
|
|
completeAnimation: function (component)
|
|
|
|
{
|
|
|
|
if (this.hideOnComplete)
|
|
|
|
{
|
|
|
|
component.parent.visible = false;
|
|
|
|
}
|
|
|
|
|
2018-04-07 11:36:11 +00:00
|
|
|
component.stop();
|
2018-01-16 12:59:05 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Animations.Animation#getFirstTick
|
2018-04-04 15:13:45 +00:00
|
|
|
* @protected
|
2018-01-16 12:59:05 +00:00
|
|
|
* @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)
|
|
|
|
{
|
2018-04-04 15:13:45 +00:00
|
|
|
component.nextTick += component._delay;
|
2018-01-16 12:59:05 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-04-19 15:36:13 +00:00
|
|
|
* Returns the AnimationFrame at the provided index
|
2018-01-16 12:59:05 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Animations.Animation#getFrameAt
|
2018-04-04 15:13:45 +00:00
|
|
|
* @protected
|
2018-01-16 12:59:05 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-04-19 15:36:13 +00:00
|
|
|
* @param {integer} index - The index in the AnimationFrame array
|
2018-01-16 12:59:05 +00:00
|
|
|
*
|
2018-04-19 15:36:13 +00:00
|
|
|
* @return {Phaser.Animations.AnimationFrame} The frame at the index provided from the animation sequence
|
2018-01-16 12:59:05 +00:00
|
|
|
*/
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-01-24 23:50:46 +00:00
|
|
|
// Could be an integer or a string
|
2018-01-16 12:59:05 +00:00
|
|
|
var frame = GetValue(item, 'frame', 0);
|
|
|
|
|
2018-01-24 23:50:46 +00:00
|
|
|
// 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.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;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-04-04 15:13:45 +00:00
|
|
|
* Loads the Animation values into the Animation Component.
|
2018-01-16 12:59:05 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Animations.Animation#load
|
2018-04-04 15:13:45 +00:00
|
|
|
* @private
|
2018-01-16 12:59:05 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-01 12:11:25 +00:00
|
|
|
* @param {Phaser.GameObjects.Components.Animation} component - The Animation Component to load values into.
|
|
|
|
* @param {integer} startFrame - The start frame of the animation to load.
|
2018-01-16 12:59:05 +00:00
|
|
|
*/
|
|
|
|
load: function (component, startFrame)
|
|
|
|
{
|
|
|
|
if (startFrame >= this.frames.length)
|
|
|
|
{
|
|
|
|
startFrame = 0;
|
|
|
|
}
|
2017-04-04 15:32:33 +00:00
|
|
|
|
2018-01-16 12:59:05 +00:00
|
|
|
if (component.currentAnim !== this)
|
|
|
|
{
|
|
|
|
component.currentAnim = this;
|
|
|
|
|
|
|
|
component.frameRate = this.frameRate;
|
|
|
|
component.duration = this.duration;
|
|
|
|
component.msPerFrame = this.msPerFrame;
|
|
|
|
component.skipMissedFrames = this.skipMissedFrames;
|
2018-04-04 15:13:45 +00:00
|
|
|
|
2018-01-16 12:59:05 +00:00
|
|
|
component._delay = this.delay;
|
|
|
|
component._repeat = this.repeat;
|
|
|
|
component._repeatDelay = this.repeatDelay;
|
|
|
|
component._yoyo = this.yoyo;
|
|
|
|
}
|
|
|
|
|
2018-07-22 14:44:57 +00:00
|
|
|
var frame = this.frames[startFrame];
|
|
|
|
|
2018-07-24 12:36:15 +00:00
|
|
|
if (startFrame === 0 && !component.forward)
|
2018-07-22 14:44:57 +00:00
|
|
|
{
|
|
|
|
frame = this.getLastFrame();
|
|
|
|
}
|
|
|
|
|
|
|
|
component.updateFrame(frame);
|
2018-01-16 12:59:05 +00:00
|
|
|
},
|
|
|
|
|
2018-04-04 16:14:43 +00:00
|
|
|
/**
|
|
|
|
* Returns the frame closest to the given progress value between 0 and 1.
|
|
|
|
*
|
|
|
|
* @method Phaser.Animations.Animation#getFrameByProgress
|
|
|
|
* @since 3.4.0
|
|
|
|
*
|
2018-06-26 22:19:14 +00:00
|
|
|
* @param {number} value - A value between 0 and 1.
|
2018-04-04 16:14:43 +00:00
|
|
|
*
|
2018-06-01 12:11:25 +00:00
|
|
|
* @return {Phaser.Animations.AnimationFrame} The frame closest to the given progress value.
|
2018-04-04 16:14:43 +00:00
|
|
|
*/
|
|
|
|
getFrameByProgress: function (value)
|
|
|
|
{
|
|
|
|
value = Clamp(value, 0, 1);
|
|
|
|
|
|
|
|
return FindClosestInSorted(value, this.frames, 'progress');
|
|
|
|
},
|
|
|
|
|
2018-01-16 12:59:05 +00:00
|
|
|
/**
|
2018-06-01 12:11:25 +00:00
|
|
|
* Advance the animation frame.
|
2018-01-16 12:59:05 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Animations.Animation#nextFrame
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-06-01 12:11:25 +00:00
|
|
|
* @param {Phaser.GameObjects.Components.Animation} component - The Animation Component to advance.
|
2018-01-16 12:59:05 +00:00
|
|
|
*/
|
|
|
|
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)
|
2018-05-15 08:40:22 +00:00
|
|
|
if (component._yoyo)
|
2018-01-16 12:59:05 +00:00
|
|
|
{
|
2018-09-07 16:19:19 +00:00
|
|
|
this.handleYoyoFrame(component, false);
|
2018-01-16 12:59:05 +00:00
|
|
|
}
|
|
|
|
else if (component.repeatCounter > 0)
|
|
|
|
{
|
|
|
|
// Repeat (happens before complete)
|
2018-07-22 17:57:07 +00:00
|
|
|
|
2018-07-24 12:28:56 +00:00
|
|
|
if (component._reverse && component.forward)
|
2018-07-22 17:57:07 +00:00
|
|
|
{
|
|
|
|
component.forward = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.repeatAnimation(component);
|
|
|
|
}
|
2018-01-16 12:59:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.completeAnimation(component);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-09-07 16:19:19 +00:00
|
|
|
this.updateAndGetNextTick(component, frame.nextFrame);
|
2018-01-16 12:59:05 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-09-01 15:40:26 +00:00
|
|
|
/**
|
|
|
|
* Handle the yoyo functionality in nextFrame and previousFrame methods.
|
|
|
|
*
|
2018-09-07 16:19:19 +00:00
|
|
|
* @method Phaser.Animations.Animation#handleYoyoFrame
|
|
|
|
* @private
|
2018-09-01 15:40:26 +00:00
|
|
|
* @since 3.12.0
|
|
|
|
*
|
|
|
|
* @param {Phaser.GameObjects.Components.Animation} component - The Animation Component to advance.
|
2018-09-07 16:19:19 +00:00
|
|
|
* @param {boolean} isReverse - Is animation in reverse mode? (Default: false)
|
2018-09-01 15:40:26 +00:00
|
|
|
*/
|
2018-09-07 16:19:19 +00:00
|
|
|
handleYoyoFrame: function (component, isReverse)
|
2018-09-01 15:40:26 +00:00
|
|
|
{
|
|
|
|
if (!isReverse) { isReverse = false; }
|
|
|
|
|
|
|
|
if (component._reverse === !isReverse && component.repeatCounter > 0)
|
|
|
|
{
|
|
|
|
component.forward = isReverse;
|
2018-09-07 16:19:19 +00:00
|
|
|
|
2018-09-01 15:40:26 +00:00
|
|
|
this.repeatAnimation(component);
|
2018-09-07 16:19:19 +00:00
|
|
|
|
2018-09-01 15:40:26 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (component._reverse !== isReverse && component.repeatCounter === 0)
|
|
|
|
{
|
|
|
|
this.completeAnimation(component);
|
2018-09-07 16:19:19 +00:00
|
|
|
|
2018-09-01 15:40:26 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
component.forward = isReverse;
|
2018-09-07 16:19:19 +00:00
|
|
|
|
|
|
|
var frame = (isReverse) ? component.currentFrame.nextFrame : component.currentFrame.prevFrame;
|
|
|
|
|
|
|
|
this.updateAndGetNextTick(component, frame);
|
2018-09-01 15:40:26 +00:00
|
|
|
},
|
|
|
|
|
2018-07-22 14:44:57 +00:00
|
|
|
/**
|
|
|
|
* Returns the animation last frame.
|
|
|
|
*
|
|
|
|
* @method Phaser.Animations.Animation#getLastFrame
|
2018-07-24 12:28:56 +00:00
|
|
|
* @since 3.12.0
|
2018-07-22 14:44:57 +00:00
|
|
|
*
|
|
|
|
* @return {Phaser.Animations.AnimationFrame} component - The Animation Last Frame.
|
|
|
|
*/
|
|
|
|
getLastFrame: function ()
|
|
|
|
{
|
|
|
|
return this.frames[this.frames.length - 1];
|
|
|
|
},
|
|
|
|
|
2018-01-16 12:59:05 +00:00
|
|
|
/**
|
|
|
|
* [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
|
|
|
|
|
2018-07-22 17:57:07 +00:00
|
|
|
if (component._yoyo)
|
2018-01-16 12:59:05 +00:00
|
|
|
{
|
2018-09-07 16:19:19 +00:00
|
|
|
this.handleYoyoFrame(component, true);
|
2018-07-22 17:57:07 +00:00
|
|
|
}
|
|
|
|
else if (component.repeatCounter > 0)
|
|
|
|
{
|
2018-07-24 12:28:56 +00:00
|
|
|
if (component._reverse && !component.forward)
|
2018-07-22 14:44:57 +00:00
|
|
|
{
|
|
|
|
component.currentFrame = this.getLastFrame();
|
2018-09-01 15:40:26 +00:00
|
|
|
this.repeatAnimation(component);
|
2018-07-22 14:44:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Repeat (happens before complete)
|
2018-07-22 17:57:07 +00:00
|
|
|
component.forward = true;
|
2018-07-22 14:44:57 +00:00
|
|
|
this.repeatAnimation(component);
|
|
|
|
}
|
2018-01-16 12:59:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.completeAnimation(component);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-09-07 16:19:19 +00:00
|
|
|
this.updateAndGetNextTick(component, frame.prevFrame);
|
2018-01-16 12:59:05 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-07-22 17:57:07 +00:00
|
|
|
/**
|
2018-09-07 16:19:19 +00:00
|
|
|
* Update Frame and Wait next tick.
|
2018-07-22 17:57:07 +00:00
|
|
|
*
|
2018-09-07 16:19:19 +00:00
|
|
|
* @method Phaser.Animations.Animation#updateAndGetNextTick
|
|
|
|
* @private
|
2018-07-24 12:28:56 +00:00
|
|
|
* @since 3.12.0
|
2018-07-22 17:57:07 +00:00
|
|
|
*
|
2018-09-07 16:19:19 +00:00
|
|
|
* @param {Phaser.Animations.AnimationFrame} frame - An Animation frame.
|
2018-07-22 17:57:07 +00:00
|
|
|
*/
|
2018-09-07 16:19:19 +00:00
|
|
|
updateAndGetNextTick: function (component, frame)
|
2018-07-22 17:57:07 +00:00
|
|
|
{
|
|
|
|
component.updateFrame(frame);
|
2018-09-07 16:19:19 +00:00
|
|
|
|
2018-07-22 17:57:07 +00:00
|
|
|
this.getNextTick(component);
|
|
|
|
},
|
|
|
|
|
2018-01-16 12:59:05 +00:00
|
|
|
/**
|
|
|
|
* [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;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-04-19 15:36:13 +00:00
|
|
|
* Removes a frame from the AnimationFrame array at the provided index
|
|
|
|
* and updates the animation accordingly.
|
2018-01-16 12:59:05 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Animations.Animation#removeFrameAt
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-04-19 15:36:13 +00:00
|
|
|
* @param {integer} index - The index in the AnimationFrame array
|
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
|
|
|
*/
|
|
|
|
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)
|
|
|
|
{
|
2018-04-07 11:36:11 +00:00
|
|
|
if (component._pendingStop === 2)
|
|
|
|
{
|
|
|
|
return this.completeAnimation(component);
|
|
|
|
}
|
|
|
|
|
2018-01-16 12:59:05 +00:00
|
|
|
if (component._repeatDelay > 0 && component.pendingRepeat === false)
|
|
|
|
{
|
|
|
|
component.pendingRepeat = true;
|
|
|
|
component.accumulator -= component.nextTick;
|
2018-04-04 15:13:45 +00:00
|
|
|
component.nextTick += component._repeatDelay;
|
2018-01-16 12:59:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
component.repeatCounter--;
|
|
|
|
|
2018-07-22 14:44:57 +00:00
|
|
|
component.updateFrame(component.currentFrame[(component.forward) ? 'nextFrame' : 'prevFrame']);
|
2018-01-16 12:59:05 +00:00
|
|
|
|
2018-04-07 11:36:11 +00:00
|
|
|
if (component.isPlaying)
|
|
|
|
{
|
|
|
|
this.getNextTick(component);
|
2018-01-16 12:59:05 +00:00
|
|
|
|
2018-04-07 11:36:11 +00:00
|
|
|
component.pendingRepeat = false;
|
2018-01-16 12:59:05 +00:00
|
|
|
|
2018-12-06 15:39:47 +00:00
|
|
|
var frame = component.currentFrame;
|
|
|
|
var parent = component.parent;
|
2018-12-06 15:28:48 +00:00
|
|
|
|
2018-12-06 15:39:47 +00:00
|
|
|
this.emit('repeat', this, frame);
|
|
|
|
|
|
|
|
parent.emit('animationrepeat-' + this.key, this, frame, component.repeatCounter, parent);
|
|
|
|
|
|
|
|
parent.emit('animationrepeat', this, frame, component.repeatCounter, parent);
|
2018-01-16 12:59:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-10-19 11:32:43 +00:00
|
|
|
* Sets the texture frame the animation uses for rendering.
|
2018-01-16 12:59:05 +00:00
|
|
|
*
|
|
|
|
* @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);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-10-19 11:32:43 +00:00
|
|
|
* Converts the animation data to JSON.
|
2018-01-16 12:59:05 +00:00
|
|
|
*
|
|
|
|
* @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
|
|
|
*/
|
2017-05-02 15:49:48 +00:00
|
|
|
pause: function ()
|
|
|
|
{
|
|
|
|
this.paused = true;
|
2018-01-16 12:59:05 +00:00
|
|
|
|
|
|
|
return this;
|
2017-05-02 15:49:48 +00:00
|
|
|
},
|
|
|
|
|
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
|
|
|
*/
|
2017-05-02 15:49:48 +00:00
|
|
|
resume: function ()
|
|
|
|
{
|
|
|
|
this.paused = false;
|
2018-01-16 12:59:05 +00:00
|
|
|
|
|
|
|
return this;
|
2017-05-02 15:49:48 +00:00
|
|
|
},
|
|
|
|
|
2018-01-16 12:59:05 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Animations.Animation#destroy
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-04-04 15:32:33 +00:00
|
|
|
destroy: function ()
|
|
|
|
{
|
2018-12-06 15:28:48 +00:00
|
|
|
this.removeAllListeners();
|
|
|
|
|
2018-04-04 16:14:43 +00:00
|
|
|
this.manager.off('pauseall', this.pause, this);
|
|
|
|
this.manager.off('resumeall', this.resume, this);
|
|
|
|
|
|
|
|
this.manager.remove(this.key);
|
|
|
|
|
|
|
|
for (var i = 0; i < this.frames.length; i++)
|
|
|
|
{
|
|
|
|
this.frames[i].destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.frames = [];
|
|
|
|
|
|
|
|
this.manager = null;
|
2017-04-04 15:32:33 +00:00
|
|
|
}
|
2017-06-30 14:47:51 +00:00
|
|
|
|
|
|
|
});
|
2017-04-04 15:32:33 +00:00
|
|
|
|
|
|
|
module.exports = Animation;
|