55 */
66
77var Class = require ( '../../utils/Class' ) ;
8+ var CustomMap = require ( '../../structs/Map' ) ;
89var GetFastValue = require ( '../../utils/object/GetFastValue' ) ;
910var Events = require ( '../../animations/events' ) ;
11+ var AnimationClass = require ( '../../animations/Animation' ) ;
1012
1113/**
1214 * @classdesc
@@ -52,7 +54,30 @@ var Animation = new Class({
5254 */
5355 this . animationManager = parent . scene . sys . anims ;
5456
55- this . animationManager . on ( Events . REMOVE_ANIMATION , this . remove , this ) ;
57+ this . animationManager . on ( Events . REMOVE_ANIMATION , this . globalRemove , this ) ;
58+
59+ /**
60+ * A reference to the Texture Manager.
61+ *
62+ * @name Phaser.GameObjects.Components.Animation#textureManager
63+ * @type {Phaser.Textures.TextureManager }
64+ * @protected
65+ * @since 3.50.0
66+ */
67+ this . textureManager = this . animationManager . textureManager ;
68+
69+ /**
70+ * The Animations stored locally in this Animation component.
71+ *
72+ * Do not modify the contents of this Map directly, instead use the
73+ * `add`, `create` and `remove` methods of this class instead.
74+ *
75+ * @name Phaser.GameObjects.Components.Animation#anims
76+ * @type {Phaser.Structs.Map.<string, Phaser.Animations.Animation> }
77+ * @protected
78+ * @since 3.50.0
79+ */
80+ this . anims = null ;
5681
5782 /**
5883 * Is an animation currently playing or not?
@@ -262,7 +287,6 @@ var Animation = new Class({
262287 */
263288 this . yoyo = false ;
264289
265-
266290 /**
267291 * Should the GameObject's `visible` property be set to `true` when the animation starts to play?
268292 *
@@ -512,8 +536,8 @@ var Animation = new Class({
512536 var manager = this . animationManager ;
513537 var animKey = ( typeof key === 'string' ) ? key : GetFastValue ( key , 'key' , null ) ;
514538
515- // Get the animation from the Animation Manager
516- var anim = manager . get ( animKey ) ;
539+ // Get the animation, first from the local map and, if not found, from the Animation Manager
540+ var anim = ( this . exists ( animKey ) ) ? this . get ( animKey ) : manager . get ( animKey ) ;
517541
518542 if ( ! anim )
519543 {
@@ -552,7 +576,7 @@ var Animation = new Class({
552576
553577 if ( startFrame === 0 && ! this . forward )
554578 {
555- frame = this . getLastFrame ( ) ;
579+ frame = anim . getLastFrame ( ) ;
556580 }
557581
558582 this . currentFrame = frame ;
@@ -668,10 +692,11 @@ var Animation = new Class({
668692 } ,
669693
670694 /**
671- * Waits for the current animation to complete one 'repeat' cycle, then starts playback of the given animation.
695+ * Waits for the current animation to complete the `repeatCount` number of repeat cycles, then starts playback
696+ * of the given animation.
672697 *
673- * You can use this to ensure there are no harsh ' jumps' between two sets of animations, i.e. going from an
674- * idle animation to a walking animation.
698+ * You can use this to ensure there are no harsh jumps between two sets of animations, i.e. going from an
699+ * idle animation to a walking animation, by making them blend smoothly into each other .
675700 *
676701 * If no animation is currently running, the given one will start immediately.
677702 *
@@ -720,9 +745,55 @@ var Animation = new Class({
720745 } ,
721746
722747 /**
723- * Plays an Animation on a Game Object that has the Animation component, such as a Sprite.
748+ * Start playing the given animation on this Sprite.
749+ *
750+ * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite.
751+ *
752+ * The benefit of a global animation is that multiple Sprites can all play the same animation, without
753+ * having to duplicate the data. You can just create it once and then play it on any Sprite.
724754 *
725- * Animations are stored in the global Animation Manager and are referenced by a unique string-based key.
755+ * The following code shows how to create a global repeating animation. The animation will be created
756+ * from all of the frames within the sprite sheet that was loaded with the key 'muybridge':
757+ *
758+ * ```javascript
759+ * var config = {
760+ * key: 'run',
761+ * frames: 'muybridge',
762+ * frameRate: 15,
763+ * repeat: -1
764+ * };
765+ *
766+ * // This code should be run from within a Scene:
767+ * this.anims.create(config);
768+ * ```
769+ *
770+ * However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone,
771+ * you can call the `Animation.create` method instead. It accepts the exact same parameters as when
772+ * creating a global animation, however the resulting data is kept locally in this Sprite.
773+ *
774+ * With the animation created, either globally or locally, you can now play it on this Sprite:
775+ *
776+ * ```javascript
777+ * this.add.sprite(x, y).play('run');
778+ * ```
779+ *
780+ * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config
781+ * object instead:
782+ *
783+ * ```javascript
784+ * this.add.sprite(x, y).play({ key: 'run', frameRate: 24 });
785+ * ```
786+ *
787+ * When playing an animation on a Sprite it will first check to see if it can find a matching key
788+ * locally within the Sprite. If it can, it will play the local animation. If not, it will then
789+ * search the global Animation Manager and look for it there.
790+ *
791+ * If you need a Sprite to be able to play both local and global animations, make sure they don't
792+ * have conflicting keys.
793+ *
794+ * See the documentation for the `PlayAnimationConfig` config object for more details about this.
795+ *
796+ * Also, see the documentation in the Animation Manager for further details on creating animations.
726797 *
727798 * @method Phaser.GameObjects.Components.Animation#play
728799 * @fires Phaser.Animations.Events#ANIMATION_START
@@ -757,7 +828,55 @@ var Animation = new Class({
757828 } ,
758829
759830 /**
760- * Plays an Animation in reverse on the Game Object that owns this Animation Component.
831+ * Start playing the given animation on this Sprite, in reverse.
832+ *
833+ * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite.
834+ *
835+ * The benefit of a global animation is that multiple Sprites can all play the same animation, without
836+ * having to duplicate the data. You can just create it once and then play it on any Sprite.
837+ *
838+ * The following code shows how to create a global repeating animation. The animation will be created
839+ * from all of the frames within the sprite sheet that was loaded with the key 'muybridge':
840+ *
841+ * ```javascript
842+ * var config = {
843+ * key: 'run',
844+ * frames: 'muybridge',
845+ * frameRate: 15,
846+ * repeat: -1
847+ * };
848+ *
849+ * // This code should be run from within a Scene:
850+ * this.anims.create(config);
851+ * ```
852+ *
853+ * However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone,
854+ * you can call the `Animation.create` method instead. It accepts the exact same parameters as when
855+ * creating a global animation, however the resulting data is kept locally in this Sprite.
856+ *
857+ * With the animation created, either globally or locally, you can now play it on this Sprite:
858+ *
859+ * ```javascript
860+ * this.add.sprite(x, y).playReverse('run');
861+ * ```
862+ *
863+ * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config
864+ * object instead:
865+ *
866+ * ```javascript
867+ * this.add.sprite(x, y).playReverse({ key: 'run', frameRate: 24 });
868+ * ```
869+ *
870+ * When playing an animation on a Sprite it will first check to see if it can find a matching key
871+ * locally within the Sprite. If it can, it will play the local animation. If not, it will then
872+ * search the global Animation Manager and look for it there.
873+ *
874+ * If you need a Sprite to be able to play both local and global animations, make sure they don't
875+ * have conflicting keys.
876+ *
877+ * See the documentation for the `PlayAnimationConfig` config object for more details about this.
878+ *
879+ * Also, see the documentation in the Animation Manager for further details on creating animations.
761880 *
762881 * @method Phaser.GameObjects.Components.Animation#playReverse
763882 * @fires Phaser.Animations.Events#ANIMATION_START
@@ -1041,13 +1160,13 @@ var Animation = new Class({
10411160 /**
10421161 * Handle the removal of an animation from the Animation Manager.
10431162 *
1044- * @method Phaser.GameObjects.Components.Animation#remove
1045- * @since 3.0 .0
1163+ * @method Phaser.GameObjects.Components.Animation#globalRemove
1164+ * @since 3.50 .0
10461165 *
10471166 * @param {string } [key] - The key of the removed Animation.
10481167 * @param {Phaser.Animations.Animation } [animation] - The removed Animation.
10491168 */
1050- remove : function ( key , animation )
1169+ globalRemove : function ( key , animation )
10511170 {
10521171 if ( animation === undefined ) { animation = this . currentAnim ; }
10531172
@@ -1479,6 +1598,117 @@ var Animation = new Class({
14791598 return this . parent ;
14801599 } ,
14811600
1601+ /**
1602+ * Get an Animation instance that has been created locally on this Sprite.
1603+ *
1604+ * See the `create` method for more details.
1605+ *
1606+ * @method Phaser.GameObjects.Components.Animation#get
1607+ * @since 3.50.0
1608+ *
1609+ * @param {string } key - The key of the Animation to retrieve.
1610+ *
1611+ * @return {Phaser.Animations.Animation } The Animation, or `undefined` if the key is invalid.
1612+ */
1613+ get : function ( key )
1614+ {
1615+ return ( this . anims && this . anims . get ( key ) ) ;
1616+ } ,
1617+
1618+ /**
1619+ * Checks to see if the given key is already used locally within the animations stored on this Sprite.
1620+ *
1621+ * @method Phaser.GameObjects.Components.Animation#exists
1622+ * @since 3.50.0
1623+ *
1624+ * @param {string } key - The key of the Animation to check.
1625+ *
1626+ * @return {boolean } `true` if the Animation exists locally, or `false` if the key is available.
1627+ */
1628+ exists : function ( key )
1629+ {
1630+ return ( this . anims && this . anims . has ( key ) ) ;
1631+ } ,
1632+
1633+ /**
1634+ * Creates a new Animation that is local specifically to this Sprite.
1635+ *
1636+ * When a Sprite owns an animation, it is kept out of the global Animation Manager, which means
1637+ * you're free to use keys that may be already defined there. Unless you specifically need a Sprite
1638+ * to have a unique animation, you should favor using global animations instead, as they allow for
1639+ * the same animation to be used across multiple Sprites, saving on memory. However, if this Sprite
1640+ * is the only one to use this animation, it's sensible to create it here.
1641+ *
1642+ * If an invalid key is given this method will return `false`.
1643+ *
1644+ * If you pass the key of an animation that already exists locally, that animation will be returned.
1645+ *
1646+ * A brand new animation is only created if the key is valid and not already in use by this Sprite.
1647+ *
1648+ * If you wish to re-use an existing key, call the `remove` method first, then this method.
1649+ *
1650+ * @method Phaser.GameObjects.Components.Animation#create
1651+ * @since 3.50.0
1652+ *
1653+ * @param {Phaser.Types.Animations.Animation } config - The configuration settings for the Animation.
1654+ *
1655+ * @return {(Phaser.Animations.Animation|false) } The Animation that was created, or `false` if the key is already in use.
1656+ */
1657+ create : function ( config )
1658+ {
1659+ var key = config . key ;
1660+
1661+ var anim = false ;
1662+
1663+ if ( key )
1664+ {
1665+ anim = this . get ( key ) ;
1666+
1667+ if ( ! anim )
1668+ {
1669+ anim = new AnimationClass ( this , key , config ) ;
1670+
1671+ if ( ! this . anims )
1672+ {
1673+ this . anims = new CustomMap ( ) ;
1674+ }
1675+
1676+ this . anims . set ( key , anim ) ;
1677+ }
1678+ }
1679+
1680+ return anim ;
1681+ } ,
1682+
1683+ /**
1684+ * Removes a locally created Animation from this Sprite, based on the given key.
1685+ *
1686+ * Once an Animation has been removed, this Sprite cannot play it again without re-creating it.
1687+ *
1688+ * @method Phaser.GameObjects.Components.Animation#remove
1689+ * @since 3.50.0
1690+ *
1691+ * @param {string } key - The key of the animation to remove.
1692+ *
1693+ * @return {Phaser.Animations.Animation } The Animation instance that was removed from this Sprite, if the key was valid.
1694+ */
1695+ remove : function ( key )
1696+ {
1697+ var anim = this . get ( key ) ;
1698+
1699+ if ( anim )
1700+ {
1701+ if ( this . currentAnim === anim )
1702+ {
1703+ this . stop ( ) ;
1704+ }
1705+
1706+ this . anims . delete ( key ) ;
1707+ }
1708+
1709+ return anim ;
1710+ } ,
1711+
14821712 /**
14831713 * Destroy this Animation component.
14841714 *
@@ -1489,7 +1719,12 @@ var Animation = new Class({
14891719 */
14901720 destroy : function ( )
14911721 {
1492- this . animationManager . off ( Events . REMOVE_ANIMATION , this . remove , this ) ;
1722+ this . animationManager . off ( Events . REMOVE_ANIMATION , this . globalRemove , this ) ;
1723+
1724+ if ( this . anims )
1725+ {
1726+ this . anims . clear ( ) ;
1727+ }
14931728
14941729 this . animationManager = null ;
14951730 this . parent = null ;
0 commit comments