1 /**************************************************************************** 2 Copyright (c) 2011-2012 cocos2d-x.org 3 Copyright (c) 2013-2014 Chukong Technologies Inc. 4 5 http://www.cocos2d-x.org 6 7 Permission is hereby granted, free of charge, to any person obtaining a copy 8 of this software and associated documentation files (the "Software"), to deal 9 in the Software without restriction, including without limitation the rights 10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 copies of the Software, and to permit persons to whom the Software is 12 furnished to do so, subject to the following conditions: 13 14 The above copyright notice and this permission notice shall be included in 15 all copies or substantial portions of the Software. 16 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 THE SOFTWARE. 24 ****************************************************************************/ 25 26 //animation type 27 /** 28 * The animation just have one frame 29 * @constant 30 * @type {number} 31 */ 32 ccs.ANIMATION_TYPE_SINGLE_FRAME = -4; 33 /** 34 * The animation isn't loop 35 * @constant 36 * @type {number} 37 */ 38 ccs.ANIMATION_TYPE_NO_LOOP = -3; 39 /** 40 * The animation to loop from front 41 * @constant 42 * @type {number} 43 */ 44 ccs.ANIMATION_TYPE_TO_LOOP_FRONT = -2; 45 /** 46 * The animation to loop from back 47 * @constant 48 * @type {number} 49 */ 50 ccs.ANIMATION_TYPE_TO_LOOP_BACK = -1; 51 /** 52 * The animation loop from front 53 * @constant 54 * @type {number} 55 */ 56 ccs.ANIMATION_TYPE_LOOP_FRONT = 0; 57 /** 58 * The animation loop from back 59 * @constant 60 * @type {number} 61 */ 62 ccs.ANIMATION_TYPE_LOOP_BACK = 1; 63 /** 64 * The animation max 65 * @constant 66 * @type {number} 67 */ 68 ccs.ANIMATION_TYPE_MAX = 2; 69 70 /** 71 * The Base Process class for Cocostudio. 72 * @class 73 * @extends ccs.Class 74 * 75 * @property {Number} currentFrameIndex - <@readonly> The current frame's index 76 * @property {Boolean} paused - <@readonly> Indicate whether the process is paused 77 * @property {Boolean} completed - <@readonly> Indicate whether the process is done 78 * @property {Number} currentPercent - <@readonly> The current percentage of the process 79 * @property {Number} rawDuration - <@readonly> The duration 80 * @property {Number} loop - <@readonly> The number of loop 81 * @property {Number} tweenEasing - <@readonly> The tween easing 82 * @property {Number} animationInterval - The animation internal 83 * @property {Number} processScale - The process scale 84 * @property {Boolean} playing - <@readonly> Indicate whether the process is playing 85 */ 86 ccs.ProcessBase = ccs.Class.extend(/** @lends ccs.ProcessBase# */{ 87 _processScale: 1, 88 _isComplete: true, 89 _isPause: true, 90 _isPlaying: false, 91 _currentPercent: 0.0, 92 _rawDuration: 0, 93 _loopType: 0, 94 _tweenEasing: 0, 95 animationInternal: null, 96 _currentFrame: 0, 97 _durationTween: 0, 98 _nextFrameIndex: 0, 99 _curFrameIndex: null, 100 _isLoopBack: false, 101 102 /** 103 * Constructor of ccs.ProcessBase 104 */ 105 ctor: function () { 106 this._processScale = 1; 107 this._isComplete = true; 108 this._isPause = true; 109 this._isPlaying = false; 110 this._currentFrame = 0; 111 this._currentPercent = 0.0; 112 this._durationTween = 0; 113 this._rawDuration = 0; 114 this._loopType = ccs.ANIMATION_TYPE_LOOP_BACK; 115 this._tweenEasing = ccs.TweenType.LINEAR; 116 this.animationInternal = 1 / 60; 117 this._curFrameIndex = 0; 118 this._durationTween = 0; 119 this._isLoopBack = false; 120 }, 121 122 /** 123 * Pauses the Process 124 */ 125 pause: function () { 126 this._isPause = true; 127 this._isPlaying = false; 128 }, 129 130 /** 131 * Resumes the Process 132 */ 133 resume: function () { 134 this._isPause = false; 135 this._isPlaying = true; 136 }, 137 138 /** 139 * Stops the Process 140 */ 141 stop: function () { 142 this._isComplete = true; 143 this._isPlaying = false; 144 }, 145 146 /** 147 * Plays animation by animation name. 148 * @param {Number} durationTo The frames between two animation changing-over. 149 * It's meaning is changing to this animation need how many frames 150 * -1 : use the value from MovementData get from flash design panel 151 * @param {Number} durationTween The frame count you want to play in the game. 152 * if _durationTween is 80, then the animation will played 80 frames in a loop 153 * -1 : use the value from MovementData get from flash design panel 154 * @param {Number} loop Whether the animation is loop 155 * loop < 0 : use the value from MovementData get from flash design panel 156 * loop = 0 : this animation is not loop 157 * loop > 0 : this animation is loop 158 * @param {Number} tweenEasing Tween easing is used for calculate easing effect 159 * TWEEN_EASING_MAX : use the value from MovementData get from flash design panel 160 * -1 : fade out 161 * 0 : line 162 * 1 : fade in 163 * 2 : fade in and out 164 */ 165 play: function (durationTo, durationTween, loop, tweenEasing) { 166 this._isComplete = false; 167 this._isPause = false; 168 this._isPlaying = true; 169 this._currentFrame = 0; 170 /* 171 * Set m_iTotalFrames to durationTo, it is used for change tween between two animation. 172 * When changing end, m_iTotalFrames will be set to _durationTween 173 */ 174 this._nextFrameIndex = durationTo; 175 this._tweenEasing = tweenEasing; 176 }, 177 178 /** 179 * Update process' state. 180 * @param {Number} dt 181 */ 182 update: function (dt) { 183 if (this._isComplete || this._isPause) 184 return; 185 186 /* 187 * Fileter the m_iDuration <=0 and dt >1 188 * If dt>1, generally speaking the reason is the device is stuck. 189 */ 190 if (this._rawDuration <= 0 || dt > 1) 191 return; 192 193 var locNextFrameIndex = this._nextFrameIndex === undefined ? 0 : this._nextFrameIndex; 194 var locCurrentFrame = this._currentFrame; 195 if (locNextFrameIndex <= 0) { 196 this._currentPercent = 1; 197 locCurrentFrame = 0; 198 } else { 199 /* 200 * update currentFrame, every update add the frame passed. 201 * dt/this.animationInternal determine it is not a frame animation. If frame speed changed, it will not make our 202 * animation speed slower or quicker. 203 */ 204 locCurrentFrame += this._processScale * (dt / this.animationInternal); 205 this._currentPercent = locCurrentFrame / locNextFrameIndex; 206 207 /* 208 * if currentFrame is bigger or equal than this._nextFrameIndex, then reduce it util currentFrame is 209 * smaller than this._nextFrameIndex 210 */ 211 locCurrentFrame = ccs.fmodf(locCurrentFrame, locNextFrameIndex); 212 } 213 this._currentFrame = locCurrentFrame; 214 this.updateHandler(); 215 }, 216 217 /** 218 * Goes to specified frame by frameIndex. 219 * @param {Number} frameIndex 220 */ 221 gotoFrame: function (frameIndex) { 222 var locLoopType = this._loopType; 223 if (locLoopType === ccs.ANIMATION_TYPE_NO_LOOP) 224 locLoopType = ccs.ANIMATION_TYPE_MAX; 225 else if (locLoopType === ccs.ANIMATION_TYPE_TO_LOOP_FRONT) 226 locLoopType = ccs.ANIMATION_TYPE_LOOP_FRONT; 227 this._loopType = locLoopType; 228 this._curFrameIndex = frameIndex; 229 this._nextFrameIndex = this._durationTween; 230 }, 231 232 /** 233 * Returns the index of current frame. 234 * @return {Number} 235 */ 236 getCurrentFrameIndex: function () { 237 this._curFrameIndex = (this._rawDuration - 1) * this._currentPercent; 238 return this._curFrameIndex; 239 }, 240 241 /** 242 * Updates will call this handler, you can handle your logic here 243 */ 244 updateHandler: function () { 245 //override 246 }, 247 248 /** 249 * Returns whether the animation is pause 250 * @returns {boolean} 251 */ 252 isPause: function () { 253 return this._isPause; 254 }, 255 256 /** 257 * Returns whether the animation is complete 258 * @returns {boolean} 259 */ 260 isComplete: function () { 261 return this._isComplete; 262 }, 263 264 /** 265 * Returns current percent of ccs.ProcessBase 266 * @returns {number} 267 */ 268 getCurrentPercent: function () { 269 return this._currentPercent; 270 }, 271 272 /** 273 * Returns the raw duration of ccs.ProcessBase 274 * @returns {number} 275 */ 276 getRawDuration: function () { 277 return this._rawDuration; 278 }, 279 280 /** 281 * Returns loop type of ccs.ProcessBase 282 * @returns {number} 283 */ 284 getLoop: function () { 285 return this._loopType; 286 }, 287 288 /** 289 * Returns tween easing of ccs.ProcessBase 290 * @returns {number} 291 */ 292 getTweenEasing: function () { 293 return this._tweenEasing; 294 }, 295 296 /** 297 * Returns animation interval of ccs.ProcessBase 298 * @returns {number} 299 */ 300 getAnimationInternal: function () { //TODO rename getAnimationInternal to getAnimationInterval in v3.1 301 return this.animationInternal; 302 }, 303 304 /** 305 * Sets animation interval to ccs.ProcessBase. 306 * @param animationInternal 307 */ 308 setAnimationInternal: function (animationInternal) { 309 this.animationInternal = animationInternal; 310 }, 311 312 /** 313 * Returns process scale 314 * @returns {number} 315 */ 316 getProcessScale: function () { 317 return this._processScale; 318 }, 319 320 /** 321 * Sets process scale 322 * @param processScale 323 */ 324 setProcessScale: function (processScale) { 325 this._processScale = processScale; 326 }, 327 328 /** 329 * Returns whether the animation is playing 330 * @returns {boolean} 331 */ 332 isPlaying: function () { 333 return this._isPlaying; 334 } 335 }); 336 337 var _p = ccs.ProcessBase.prototype; 338 339 // Extended properties 340 /** @expose */ 341 _p.currentFrameIndex; 342 cc.defineGetterSetter(_p, "currentFrameIndex", _p.getCurrentFrameIndex); 343 /** @expose */ 344 _p.paused; 345 cc.defineGetterSetter(_p, "paused", _p.isPause); 346 /** @expose */ 347 _p.completed; 348 cc.defineGetterSetter(_p, "completed", _p.isComplete); 349 /** @expose */ 350 _p.currentPercent; 351 cc.defineGetterSetter(_p, "currentPercent", _p.getCurrentPercent); 352 /** @expose */ 353 _p.rawDuration; 354 cc.defineGetterSetter(_p, "rawDuration", _p.getRawDuration); 355 /** @expose */ 356 _p.loop; 357 cc.defineGetterSetter(_p, "loop", _p.getLoop); 358 /** @expose */ 359 _p.tweenEasing; 360 cc.defineGetterSetter(_p, "tweenEasing", _p.getTweenEasing); 361 /** @expose */ 362 _p.playing; 363 cc.defineGetterSetter(_p, "playing", _p.isPlaying); 364 365 _p = null; 366