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 this._totalDelayUnits = 0; 229 230 var locFrames = this._frames; 231 locFrames.length = 0; 232 for (var i = 0; i < arrayOfAnimationFrames.length; i++) { 233 var animFrame = arrayOfAnimationFrames[i]; 234 locFrames.push(animFrame); 235 this._totalDelayUnits += animFrame.getDelayUnits(); 236 } 237 238 return true; 239 }, 240 241 clone: function(){ 242 var animation = new cc.Animation(); 243 animation.initWithAnimationFrames(this._copyFrames(), this._delayPerUnit, this._loops); 244 animation.setRestoreOriginalFrame(this._restoreOriginalFrame); 245 return animation; 246 }, 247 248 /** 249 * @param {cc.Animation} pZone 250 */ 251 copyWithZone:function (pZone) { 252 var pCopy = new cc.Animation(); 253 pCopy.initWithAnimationFrames(this._copyFrames(), this._delayPerUnit, this._loops); 254 pCopy.setRestoreOriginalFrame(this._restoreOriginalFrame); 255 return pCopy; 256 }, 257 258 _copyFrames:function(){ 259 var copyFrames = []; 260 for(var i = 0; i< this._frames.length;i++) 261 copyFrames.push(this._frames[i].clone()); 262 return copyFrames; 263 }, 264 265 copy:function (pZone) { 266 return this.copyWithZone(null); 267 }, 268 269 /** 270 * return how many times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ... 271 * @return {Number} 272 */ 273 getLoops:function () { 274 return this._loops; 275 }, 276 277 /** 278 * set how many times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ... 279 * @param {Number} value 280 */ 281 setLoops:function (value) { 282 this._loops = value; 283 }, 284 285 /** 286 * whether or not it shall restore the original frame when the animation finishes 287 * @param {Boolean} restOrigFrame 288 */ 289 setRestoreOriginalFrame:function (restOrigFrame) { 290 this._restoreOriginalFrame = restOrigFrame; 291 }, 292 293 /** 294 * return whether or not it shall restore the original frame when the animation finishes 295 * @return {Boolean} 296 */ 297 getRestoreOriginalFrame:function () { 298 return this._restoreOriginalFrame; 299 }, 300 301 /** 302 * return duration in seconds of the whole animation. It is the result of totalDelayUnits * delayPerUnit 303 * @return {Number} 304 */ 305 getDuration:function () { 306 return this._totalDelayUnits * this._delayPerUnit; 307 }, 308 309 /** 310 * return Delay in seconds of the "delay unit" 311 * @return {Number} 312 */ 313 getDelayPerUnit:function () { 314 return this._delayPerUnit; 315 }, 316 317 /** 318 * set Delay in seconds of the "delay unit" 319 * @param {Number} delayPerUnit 320 */ 321 setDelayPerUnit:function (delayPerUnit) { 322 this._delayPerUnit = delayPerUnit; 323 }, 324 325 /** 326 * return total Delay units of the cc.Animation. 327 * @return {Number} 328 */ 329 getTotalDelayUnits:function () { 330 return this._totalDelayUnits; 331 }, 332 333 /** 334 * Initializes a cc.Animation with frames and a delay between frames 335 * @param {Array} frames 336 * @param {Number} delay 337 */ 338 initWithSpriteFrames:function (frames, delay) { 339 cc.ArrayVerifyType(frames, cc.SpriteFrame); 340 this._loops = 1; 341 delay = delay || 0; 342 this._delayPerUnit = delay; 343 this._totalDelayUnits = 0; 344 345 var locFrames = this._frames; 346 locFrames.length = 0; 347 if (frames) { 348 for (var i = 0; i < frames.length; i++) { 349 var frame = frames[i]; 350 var animFrame = new cc.AnimationFrame(); 351 animFrame.initWithSpriteFrame(frame, 1, null); 352 locFrames.push(animFrame); 353 } 354 this._totalDelayUnits += frames.length; 355 } 356 return true; 357 }, 358 /** 359 * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB, 360 * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB. 361 * This is a hack, and should be removed once JSB fixes the retain/release bug 362 */ 363 retain:function () { 364 }, 365 release:function () { 366 } 367 }); 368 369 /** 370 * Creates an animation. 371 * @param {Array} frames 372 * @param {Number} delay 373 * @param {Number} loops 374 * @return {cc.Animation} 375 * @example 376 * //Creates an animation 377 * var animation1 = cc.Animation.create(); 378 * 379 * //Create an animation with sprite frames 380 * var animFrames = []; 381 * var frame = cache.getSpriteFrame("grossini_dance_01.png"); 382 * animFrames.push(frame); 383 * var animation2 = cc.Animation.create(animFrames); 384 * 385 * //Create an animation with sprite frames and delay 386 * var animation3 = cc.Animation.create(animFrames, 0.2); 387 */ 388 cc.Animation.create = function (frames, delay, loops) { 389 var len = arguments.length; 390 var animation = new cc.Animation(); 391 if (len == 0) { 392 animation.initWithSpriteFrames(null, 0); 393 } else if (len == 2) { 394 /** with frames and a delay between frames */ 395 delay = delay || 0; 396 animation.initWithSpriteFrames(frames, delay); 397 } else if (len == 3) { 398 animation.initWithAnimationFrames(frames, delay, loops); 399 } 400 return animation; 401 }; 402 403 /** 404 * Creates an animation with an array of cc.AnimationFrame, the delay per units in seconds and and how many times it should be executed. 405 * @param {Array} arrayOfAnimationFrameNames 406 * @param {Number} delayPerUnit 407 * @param {Number} loops 408 * @return {cc.Animation} 409 */ 410 cc.Animation.createWithAnimationFrames = function (arrayOfAnimationFrameNames, delayPerUnit, loops) { 411 var animation = new cc.Animation(); 412 animation.initWithAnimationFrames(arrayOfAnimationFrameNames, delayPerUnit, loops); 413 return animation; 414 }; 415 416