File:CharacterController.js
- /**
- * @module cloudkid
- */
- (function(){
-
- "use strict";
-
- // Imports
- var Animator = cloudkid.Animator;
-
- /**
- * Character Controller class is designed to play animated
- * sequences on the timeline. This is a flexible way to
- * animate characters on a timeline
- *
- * @class CharacterController
- */
- var CharacterController = function()
- {
- this.initialize();
- };
-
- var p = CharacterController.prototype;
-
- /**
- * The current stack of animations to play
- *
- * @property {Array} _animationStack
- * @private
- */
- p._animationStack = null;
-
- /**
- * The currently playing animation
- *
- * @property {CharacterClip} _currentAnimation
- * @private
- */
- p._currentAnimation = null;
-
- /**
- * Current number of loops for the current animation
- *
- * @property {int} _loops
- * @private
- */
- p._loops = 0;
-
- /**
- * If the current animation choreographies can't be interrupted
- *
- * @property {bool} _interruptable
- * @private
- */
- p._interruptable = true;
-
- /**
- * If frame dropping is allowed for this animation set
- *
- * @property {bool} _allowFrameDropping
- * @private
- */
- p._allowFrameDropping = false;
-
- /**
- * The current character
- *
- * @property {createjs.MovieClip} _character
- * @private
- */
- p._character = null;
-
- /**
- * Callback function for playing animation
- *
- * @property {function} _callback
- * @private
- */
- p._callback = null;
-
- /**
- * If this instance has been destroyed
- *
- * @property {bool} _destroyed
- * @private
- */
- p._destroyed = false;
-
- /**
- * Initiliazes this Character controller
- *
- * @function initialize
- */
- p.initialize = function()
- {
- this._animationStack = [];
- };
-
- /**
- * Set the current character, setting to null clears character
- *
- * @function setCharacter
- * @param {createjs.MovieClip} character MovieClip
- */
- p.setCharacter = function(character)
- {
- this.clear();
- this._character = character;
- if (this._character)
- {
- Debug.assert(this._character instanceof createjs.MovieClip, "character must subclass MovieClip");
- this._character.stop();
- }
- };
-
- /**
- * If we want to play a static frame
- *
- * @function gotoFrameAndStop
- * @param {String} event The frame label to stop on
- */
- p.gotoFrameAndStop = function(event)
- {
- Debug.assert(this._character, "gotoFrameAndStop() requires a character!");
- Animator.stop(this._character);
- this._animationStack.length = 0;
- this._character.gotoAndStop(event);
- };
-
- /**
- * Will play a sequence of animations
- *
- * @function playClips
- * @param {Array} clips an array of CharacterClip objects
- * @param {function} callback Callback for when the animations are either done, or
- * have been interrupted. Will pass true is interrupted,
- * false if they completed
- * @param {bool} interruptable If calling this can interrupt the current animation(s)
- * @param {bool} cancelPreviousCallback Cancel the callback the last time this was called
- * @param {bool} allowFrameDropping If frame dropping is allowed for this frame, if the Animator is doing frame drop checks
- */
- p.playClips = function(clips, callback, interruptable, cancelPreviousCallback, allowFrameDropping)
- {
- callback = callback || null;
- interruptable = interruptable || true;
- cancelPreviousCallback = cancelPreviousCallback || true;
- allowFrameDropping = allowFrameDropping || true;
-
- Debug.assert(this._character, "playClips requires a character!");
-
- if (!this._interruptable) return;
-
- Animator.stop(this._character);
-
- this._interruptable = interruptable;
-
- if (this._callback && !cancelPreviousCallback)
- {
- this._callback(true);
- }
-
- this._callback = callback;
- this._animationStack.length = 0;
- for(var c in clips)
- {
- this._animationStack.push(clips[c]);
- }
- this._allowFrameDropping = allowFrameDropping;
-
- this.startNext();
- };
-
- /**
- * Start the next animation in the sequence
- *
- * @function startNext
- */
- p.startNext = function()
- {
- this._loops = 0;
- if (this._animationStack.length > 0)
- {
- this._currentAnimation = this._animationStack.shift();
- Animator.play(
- this._character,
- this._currentAnimation.event,
- this._animationComplete.bind(this),
- [this],
- this._allowFrameDropping
- );
- }
- else if(this._callback)
- {
- this._interruptable = true;
- var cb = this._callback;
- this._callback = null;
- cb(false);
- }
- };
-
- /**
- * When the animation has completed playing
- *
- * @function _animationComplete
- * @private
- */
- p._animationComplete = function()
- {
- this._loops++;
-
- if(this._currentAnimation.loops === 0 || this._loops < this._currentAnimation.loops)
- {
- Animator.play(
- this._character,
- this._currentAnimation.event,
- this._animationComplete.bind(this),
- null,
- this._allowFrameDropping
- );
- }
- else if (this._currentAnimation.loops == this._loops)
- {
- this.startNext();
- }
- };
-
- /**
- * Clear any animations for the current character
- *
- * @function clear
- */
- p.clear = function()
- {
- if (this._character)
- {
- Animator.stop(this._character);
- }
- this._currentAnimation = null;
- this._interruptable = true;
- this._callback = null;
- this._animationStack.length = 0;
- this._loops = 0;
- };
-
- /**
- * Don't use after this
- *
- * @function destroy
- */
- p.destroy = function()
- {
- if(this._destroyed) return;
-
- this._destroyed = true;
- this.clear();
- this._character = null;
- this._animationStack = null;
- };
-
- // Assign to the cloudkid namespace
- namespace('cloudkid').CharacterController = CharacterController;
- }());
-