1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 /** 28 * <p> 29 * cc.AnimationFrame 30 * A frame of the animation. It contains information like: 31 * - sprite frame name 32 * - # of delay units. 33 * - offset 34 * </p> 35 * @class 36 * @extends cc.Class 37 */ 38 cc.AnimationFrame = cc.Class.extend(/** @lends cc.AnimationFrame# */{ 39 _spriteFrame:null, 40 _delayPerUnit:0, 41 _userInfo:null, 42 43 ctor:function () { 44 this._delayPerUnit = 0; 45 }, 46 47 clone: function(){ 48 var frame = new cc.AnimationFrame(); 49 frame.initWithSpriteFrame(this._spriteFrame.clone(), this._delayPerUnit, this._userInfo); 50 return frame; 51 }, 52 53 copyWithZone:function (pZone) { 54 return cc.clone(this); 55 }, 56 57 copy:function (pZone) { 58 var newFrame = new cc.AnimationFrame(); 59 newFrame.initWithSpriteFrame(this._spriteFrame.clone(), this._delayPerUnit, this._userInfo); 60 return newFrame; 61 }, 62 63 /** 64 * initializes the animation frame with a spriteframe, number of delay units and a notification user info 65 * @param {cc.SpriteFrame} spriteFrame 66 * @param {Number} delayUnits 67 * @param {object} userInfo 68 */ 69 initWithSpriteFrame:function (spriteFrame, delayUnits, userInfo) { 70 this._spriteFrame = spriteFrame; 71 this._delayPerUnit = delayUnits; 72 this._userInfo = userInfo; 73 74 return true; 75 }, 76 77 /** 78 * cc.SpriteFrameName to be used 79 * @return {cc.SpriteFrame} 80 */ 81 getSpriteFrame:function () { 82 return this._spriteFrame; 83 }, 84 85 /** 86 * cc.SpriteFrameName to be used 87 * @param {cc.SpriteFrame} spriteFrame 88 */ 89 setSpriteFrame:function (spriteFrame) { 90 this._spriteFrame = spriteFrame; 91 }, 92 93 /** 94 * how many units of time the frame takes getter 95 * @return {Number} 96 */ 97 getDelayUnits:function () { 98 return this._delayPerUnit; 99 }, 100 101 /** 102 * how many units of time the frame takes setter 103 * @param delayUnits 104 */ 105 setDelayUnits:function (delayUnits) { 106 this._delayPerUnit = delayUnits; 107 }, 108 109 /** 110 * <p>A cc.AnimationFrameDisplayedNotification notification will be broadcasted when the frame is displayed with this dictionary as UserInfo.<br/> 111 * If UserInfo is nil, then no notification will be broadcasted. </p> 112 * @return {object} 113 */ 114 getUserInfo:function () { 115 return this._userInfo; 116 }, 117 118 /** 119 * @param {object} userInfo 120 */ 121 setUserInfo:function (userInfo) { 122 this._userInfo = userInfo; 123 } 124 }); 125 126 /** 127 * <p> 128 * A cc.Animation object is used to perform animations on the cc.Sprite objects.<br/> 129 * <br/> 130 * The cc.Animation object contains cc.SpriteFrame objects, and a possible delay between the frames. <br/> 131 * You can animate a cc.Animation object by using the cc.Animate action. Example: <br/> 132 * </p> 133 * @class 134 * @extends cc.Class 135 * 136 * @example 137 * //create an animation object 138 * var animation = cc.Animation.create(); 139 * 140 * //add a sprite frame to this animation 141 * animation.addFrameWithFile("grossini_dance_01.png"); 142 * 143 * //create an animate with this animation 144 * var action = cc.Animate.create(animation); 145 * 146 * //run animate 147 * this._grossini.runAction(action); 148 */ 149 cc.Animation = cc.Class.extend(/** @lends cc.Animation# */{ 150 _frames:null, 151 _loops:0, 152 _restoreOriginalFrame:false, 153 _duration:0, 154 _delayPerUnit:0, 155 _totalDelayUnits:0, 156 157 /** 158 * Constructor 159 */ 160 ctor:function () { 161 this._frames = []; 162 }, 163 164 // attributes 165 166 /** 167 * return array of CCAnimationFrames 168 * @return {Array} 169 */ 170 getFrames:function () { 171 return this._frames; 172 }, 173 174 /** 175 * array of CCAnimationFrames setter 176 * @param {Array} frames 177 */ 178 setFrames:function (frames) { 179 this._frames = frames; 180 }, 181 182 /** 183 * adds a frame to a cc.Animation The frame will be added with one "delay unit". 184 * @param {cc.SpriteFrame} frame 185 */ 186 addSpriteFrame:function (frame) { 187 var animFrame = new cc.AnimationFrame(); 188 189 animFrame.initWithSpriteFrame(frame, 1, null); 190 this._frames.push(animFrame); 191 // update duration 192 this._totalDelayUnits++; 193 }, 194 195 /** 196 * Adds a frame with an image filename. Internally it will create a cc.SpriteFrame and it will add it. The frame will be added with one "delay unit". 197 * @param {String} fileName 198 */ 199 addSpriteFrameWithFile:function (fileName) { 200 var texture = cc.TextureCache.getInstance().addImage(fileName); 201 var rect = cc.RectZero(); 202 rect.size = texture.getContentSize(); 203 var frame = cc.SpriteFrame.createWithTexture(texture, rect); 204 this.addSpriteFrame(frame); 205 }, 206 207 /** 208 * Adds a frame with a texture and a rect. Internally it will create a cc.SpriteFrame and it will add it. The frame will be added with one "delay unit". 209 * @param {cc.Texture2D} texture 210 * @param {cc.Rect} rect 211 */ 212 addSpriteFrameWithTexture:function (texture, rect) { 213 var pFrame = cc.SpriteFrame.createWithTexture(texture, rect); 214 this.addSpriteFrame(pFrame); 215 }, 216 217 /** 218 * Initializes a cc.Animation with cc.AnimationFrame 219 * @param {Array} arrayOfAnimationFrames 220 * @param {Number} delayPerUnit 221 * @param {Number} loops 222 */ 223 initWithAnimationFrames:function (arrayOfAnimationFrames, delayPerUnit, loops) { 224 cc.ArrayVerifyType(arrayOfAnimationFrames, cc.AnimationFrame); 225 226 this._delayPerUnit = delayPerUnit; 227 this._loops = loops; 228 229 this.setFrames([]); 230 for (var i = 0; i < arrayOfAnimationFrames.length; i++) { 231 var animFrame = arrayOfAnimationFrames[i]; 232 this._frames.push(animFrame); 233 this._totalDelayUnits += animFrame.getDelayUnits(); 234 } 235 236 return true; 237 }, 238 239 clone: function(){ 240 var animation = new cc.Animation(); 241 animation.initWithAnimationFrames(this._copyFrames(), this._delayPerUnit, this._loops); 242 animation.setRestoreOriginalFrame(this._restoreOriginalFrame); 243 return animation; 244 }, 245 246 /** 247 * @param {cc.Animation} pZone 248 */ 249 copyWithZone:function (pZone) { 250 var pCopy = new cc.Animation(); 251 pCopy.initWithAnimationFrames(this._copyFrames(), this._delayPerUnit, this._loops); 252 pCopy.setRestoreOriginalFrame(this._restoreOriginalFrame); 253 return pCopy; 254 }, 255 256 _copyFrames:function(){ 257 var copyFrames = []; 258 for(var i = 0; i< this._frames.length;i++) 259 copyFrames.push(this._frames[i].clone()); 260 return copyFrames; 261 }, 262 263 copy:function (pZone) { 264 return this.copyWithZone(null); 265 }, 266 267 /** 268 * return how many times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ... 269 * @return {Number} 270 */ 271 getLoops:function () { 272 return this._loops; 273 }, 274 275 /** 276 * set how many times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ... 277 * @param {Number} value 278 */ 279 setLoops:function (value) { 280 this._loops = value; 281 }, 282 283 /** 284 * whether or not it shall restore the original frame when the animation finishes 285 * @param {Boolean} restOrigFrame 286 */ 287 setRestoreOriginalFrame:function (restOrigFrame) { 288 this._restoreOriginalFrame = restOrigFrame; 289 }, 290 291 /** 292 * return whether or not it shall restore the original frame when the animation finishes 293 * @return {Boolean} 294 */ 295 getRestoreOriginalFrame:function () { 296 return this._restoreOriginalFrame; 297 }, 298 299 /** 300 * return duration in seconds of the whole animation. It is the result of totalDelayUnits * delayPerUnit 301 * @return {Number} 302 */ 303 getDuration:function () { 304 return this._totalDelayUnits * this._delayPerUnit; 305 }, 306 307 /** 308 * return Delay in seconds of the "delay unit" 309 * @return {Number} 310 */ 311 getDelayPerUnit:function () { 312 return this._delayPerUnit; 313 }, 314 315 /** 316 * set Delay in seconds of the "delay unit" 317 * @param {Number} delayPerUnit 318 */ 319 setDelayPerUnit:function (delayPerUnit) { 320 this._delayPerUnit = delayPerUnit; 321 }, 322 323 /** 324 * return total Delay units of the cc.Animation. 325 * @return {Number} 326 */ 327 getTotalDelayUnits:function () { 328 return this._totalDelayUnits; 329 }, 330 331 /** 332 * Initializes a cc.Animation with frames and a delay between frames 333 * @param {Array} frames 334 * @param {Number} delay 335 */ 336 initWithSpriteFrames:function (frames, delay) { 337 cc.ArrayVerifyType(frames, cc.SpriteFrame); 338 this._loops = 1; 339 delay = delay || 0; 340 this._delayPerUnit = delay; 341 342 var tempFrames = []; 343 this.setFrames(tempFrames); 344 if (frames) { 345 for (var i = 0; i < frames.length; i++) { 346 var frame = frames[i]; 347 var animFrame = new cc.AnimationFrame(); 348 animFrame.initWithSpriteFrame(frame, 1, null); 349 this._frames.push(animFrame); 350 this._totalDelayUnits++; 351 } 352 } 353 return true; 354 }, 355 /** 356 * Currently JavaScript Bindigns (JSB), in some cases, needs to use retain and release. This is a bug in JSB, 357 * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB. 358 * This is a hack, and should be removed once JSB fixes the retain/release bug 359 */ 360 retain:function () { 361 }, 362 release:function () { 363 } 364 }); 365 366 /** 367 * Creates an animation. 368 * @param {Array} frames 369 * @param {Number} delay 370 * @param {Number} loops 371 * @return {cc.Animation} 372 * @example 373 * //Creates an animation 374 * var animation1 = cc.Animation.create(); 375 * 376 * //Create an animation with sprite frames 377 * var animFrames = []; 378 * var frame = cache.getSpriteFrame("grossini_dance_01.png"); 379 * animFrames.push(frame); 380 * var animation2 = cc.Animation.create(animFrames); 381 * 382 * //Create an animation with sprite frames and delay 383 * var animation3 = cc.Animation.create(animFrames, 0.2); 384 */ 385 cc.Animation.create = function (frames, delay, loops) { 386 var len = arguments.length; 387 var animation = new cc.Animation(); 388 if (len == 0) { 389 animation.initWithSpriteFrames(null, 0); 390 } else if (len == 2) { 391 /** with frames and a delay between frames */ 392 delay = delay || 0; 393 animation.initWithSpriteFrames(frames, delay); 394 } else if (len == 3) { 395 animation.initWithAnimationFrames(frames, delay, loops); 396 } 397 return animation; 398 }; 399 400 /** 401 * Creates an animation with an array of cc.AnimationFrame, the delay per units in seconds and and how many times it should be executed. 402 * @param {Array} arrayOfAnimationFrameNames 403 * @param {Number} delayPerUnit 404 * @param {Number} loops 405 * @return {cc.Animation} 406 */ 407 cc.Animation.createWithAnimationFrames = function (arrayOfAnimationFrameNames, delayPerUnit, loops) { 408 var animation = new cc.Animation(); 409 animation.initWithAnimationFrames(arrayOfAnimationFrameNames, delayPerUnit, loops); 410 return animation; 411 }; 412 413