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 27 //animation type 28 /** 29 * the animation just have one frame 30 * @constant 31 * @type {number} 32 */ 33 ccs.ANIMATION_TYPE_SINGLE_FRAME = -4; 34 /** 35 * the animation isn't loop 36 * @constant 37 * @type {number} 38 */ 39 ccs.ANIMATION_TYPE_NO_LOOP = -3; 40 /** 41 * the animation to loop from front 42 * @constant 43 * @type {number} 44 */ 45 ccs.ANIMATION_TYPE_TO_LOOP_FRONT = -2; 46 /** 47 * the animation to loop from back 48 * @constant 49 * @type {number} 50 */ 51 ccs.ANIMATION_TYPE_TO_LOOP_BACK = -1; 52 /** 53 * the animation loop from front 54 * @constant 55 * @type {number} 56 */ 57 ccs.ANIMATION_TYPE_LOOP_FRONT = 0; 58 /** 59 * the animation loop from back 60 * @constant 61 * @type {number} 62 */ 63 ccs.ANIMATION_TYPE_LOOP_BACK = 1; 64 /** 65 * the animation max 66 * @constant 67 * @type {number} 68 */ 69 ccs.ANIMATION_TYPE_MAX = 2; 70 71 /** 72 * Base class for ccs.ProcessBase objects. 73 * @class 74 * @extends ccs.Class 75 * 76 * @property {Number} currentFrameIndex - <@readonly> The current frame's index 77 * @property {Boolean} paused - <@readonly> Indicate whether the process is paused 78 * @property {Boolean} completed - <@readonly> Indicate whether the process is done 79 * @property {Number} currentPercent - <@readonly> The current percentage of the process 80 * @property {Number} rawDuration - <@readonly> The duration 81 * @property {Number} loop - <@readonly> The number of loop 82 * @property {Number} tweenEasing - <@readonly> The tween easing 83 * @property {Number} animationInterval - The animation internal 84 * @property {Number} processScale - The process scale 85 * @property {Boolean} playing - <@readonly> Indicate whether the process is playing 86 */ 87 ccs.ProcessBase = ccs.Class.extend(/** @lends ccs.ProcessBase# */{ 88 _processScale: 1, 89 _isComplete: true, 90 _isPause: true, 91 _isPlaying: false, 92 _currentPercent: 0.0, 93 _rawDuration: 0, 94 _loopType: 0, 95 _tweenEasing: 0, 96 animationInternal: null, 97 _currentFrame: 0, 98 _durationTween: 0, 99 _nextFrameIndex: 0, 100 _curFrameIndex: null, 101 _isLoopBack: false, 102 103 ctor: function () { 104 this._processScale = 1; 105 this._isComplete = true; 106 this._isPause = true; 107 this._isPlaying = false; 108 this._currentFrame = 0; 109 this._currentPercent = 0.0; 110 this._durationTween = 0; 111 this._rawDuration = 0; 112 this._loopType = ccs.ANIMATION_TYPE_LOOP_BACK; 113 this._tweenEasing = ccs.TweenType.linear; 114 this.animationInternal = 1 / 60; 115 this._curFrameIndex = 0; 116 this._durationTween = 0; 117 this._isLoopBack = false; 118 }, 119 120 /** 121 * Pause the Process 122 */ 123 pause: function () { 124 this._isPause = true; 125 this._isPlaying = false; 126 }, 127 128 /** 129 * Resume the Process 130 */ 131 resume: function () { 132 this._isPause = false; 133 this._isPlaying = true; 134 }, 135 136 /** 137 * Stop the Process 138 */ 139 stop: function () { 140 this._isComplete = true; 141 this._isPlaying = false; 142 }, 143 144 /** 145 * Play animation by animation name. 146 * @param {Number} durationTo The frames between two animation changing-over. 147 * It's meaning is changing to this animation need how many frames 148 * -1 : use the value from MovementData get from flash design panel 149 * @param {Number} durationTween The frame count you want to play in the game. 150 * if _durationTween is 80, then the animation will played 80 frames in a loop 151 * -1 : use the value from MovementData get from flash design panel 152 * @param {Number} loop Whether the animation is loop 153 * loop < 0 : use the value from MovementData get from flash design panel 154 * loop = 0 : this animation is not loop 155 * loop > 0 : this animation is loop 156 * @param {Number} tweenEasing Tween easing is used for calculate easing effect 157 * TWEEN_EASING_MAX : use the value from MovementData get from flash design panel 158 * -1 : fade out 159 * 0 : line 160 * 1 : fade in 161 * 2 : fade in and out 162 */ 163 play: function (durationTo, durationTween, loop, tweenEasing) { 164 this._isComplete = false; 165 this._isPause = false; 166 this._isPlaying = true; 167 this._currentFrame = 0; 168 /* 169 * Set m_iTotalFrames to durationTo, it is used for change tween between two animation. 170 * When changing end, m_iTotalFrames will be set to _durationTween 171 */ 172 this._nextFrameIndex = durationTo; 173 this._tweenEasing = tweenEasing; 174 }, 175 176 update: function (dt) { 177 if (this._isComplete || this._isPause) 178 return; 179 180 /* 181 * Fileter the m_iDuration <=0 and dt >1 182 * If dt>1, generally speaking the reason is the device is stuck. 183 */ 184 if (this._rawDuration <= 0 || dt > 1) 185 return; 186 187 var locNextFrameIndex = this._nextFrameIndex === undefined ? 0 : this._nextFrameIndex; 188 var locCurrentFrame = this._currentFrame; 189 if (locNextFrameIndex <= 0) { 190 this._currentPercent = 1; 191 locCurrentFrame = 0; 192 } else { 193 /* 194 * update currentFrame, every update add the frame passed. 195 * dt/this.animationInternal determine it is not a frame animation. If frame speed changed, it will not make our 196 * animation speed slower or quicker. 197 */ 198 locCurrentFrame += this._processScale * (dt / this.animationInternal); 199 this._currentPercent = locCurrentFrame / locNextFrameIndex; 200 201 /* 202 * if currentFrame is bigger or equal than this._nextFrameIndex, then reduce it util currentFrame is 203 * smaller than this._nextFrameIndex 204 */ 205 locCurrentFrame = ccs.fmodf(locCurrentFrame, locNextFrameIndex); 206 } 207 this._currentFrame = locCurrentFrame; 208 this.updateHandler(); 209 }, 210 211 /** 212 * goto frame 213 * @param {Number} frameIndex 214 */ 215 gotoFrame: function (frameIndex) { 216 var locLoopType = this._loopType; 217 if (locLoopType == ccs.ANIMATION_TYPE_NO_LOOP) 218 locLoopType = ccs.ANIMATION_TYPE_MAX; 219 else if (locLoopType == ccs.ANIMATION_TYPE_TO_LOOP_FRONT) 220 locLoopType = ccs.ANIMATION_TYPE_LOOP_FRONT; 221 this._loopType = locLoopType; 222 this._curFrameIndex = frameIndex; 223 this._nextFrameIndex = this._durationTween; 224 }, 225 226 /** 227 * get currentFrameIndex 228 * @return {Number} 229 */ 230 getCurrentFrameIndex: function () { 231 this._curFrameIndex = (this._rawDuration - 1) * this._currentPercent; 232 return this._curFrameIndex; 233 }, 234 235 /** 236 * update will call this handler, you can handle your logic here 237 */ 238 updateHandler: function () { 239 //override 240 }, 241 242 /** 243 * whether the animation is pause 244 * @returns {boolean} 245 */ 246 isPause: function () { 247 return this._isPause; 248 }, 249 250 /** 251 * whether the animation is complete 252 * @returns {boolean} 253 */ 254 isComplete: function () { 255 return this._isComplete; 256 }, 257 258 /** 259 * current percent getter 260 * @returns {number} 261 */ 262 getCurrentPercent: function () { 263 return this._currentPercent; 264 }, 265 266 /** 267 * rawDuration getter 268 * @returns {number} 269 */ 270 getRawDuration: function () { 271 return this._rawDuration; 272 }, 273 274 /** 275 * loop type getter 276 * @returns {number} 277 */ 278 getLoop: function () { 279 return this._loopType; 280 }, 281 282 /** 283 * tween easing getter 284 * @returns {number} 285 */ 286 getTweenEasing: function () { 287 return this._tweenEasing; 288 }, 289 290 /** 291 * animationInternal getter 292 * @returns {number} 293 */ 294 getAnimationInternal: function () { 295 return this.animationInternal; 296 }, 297 298 /** 299 * animationInternal setter 300 * @param animationInternal 301 */ 302 setAnimationInternal: function (animationInternal) { 303 this.animationInternal = animationInternal; 304 }, 305 306 /** 307 * process scale getter 308 * @returns {number} 309 */ 310 getProcessScale: function () { 311 return this._processScale; 312 }, 313 314 /** 315 * process scale setter 316 * @param processScale 317 */ 318 setProcessScale: function (processScale) { 319 this._processScale = processScale; 320 }, 321 322 /** 323 * whether the animation is playing 324 * @returns {boolean} 325 */ 326 isPlaying: function () { 327 return this._isPlaying; 328 } 329 }); 330 331 var _p = ccs.ProcessBase.prototype; 332 333 // Extended properties 334 /** @expose */ 335 _p.currentFrameIndex; 336 cc.defineGetterSetter(_p, "currentFrameIndex", _p.getCurrentFrameIndex); 337 /** @expose */ 338 _p.paused; 339 cc.defineGetterSetter(_p, "paused", _p.isPause); 340 /** @expose */ 341 _p.completed; 342 cc.defineGetterSetter(_p, "completed", _p.isComplete); 343 /** @expose */ 344 _p.currentPercent; 345 cc.defineGetterSetter(_p, "currentPercent", _p.getCurrentPercent); 346 /** @expose */ 347 _p.rawDuration; 348 cc.defineGetterSetter(_p, "rawDuration", _p.getRawDuration); 349 /** @expose */ 350 _p.loop; 351 cc.defineGetterSetter(_p, "loop", _p.getLoop); 352 /** @expose */ 353 _p.tweenEasing; 354 cc.defineGetterSetter(_p, "tweenEasing", _p.getTweenEasing); 355 /** @expose */ 356 _p.playing; 357 cc.defineGetterSetter(_p, "playing", _p.isPlaying); 358 359 _p = null; 360