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 copyWithZone:function (pZone) { 48 return cc.clone(this); 49 }, 50 51 copy:function (pZone) { 52 var newFrame = new cc.AnimationFrame(); 53 newFrame.initWithSpriteFrame(this._spriteFrame, this._delayPerUnit, this._userInfo); 54 return newFrame; 55 }, 56 57 /** 58 * initializes the animation frame with a spriteframe, number of delay units and a notification user info 59 * @param {cc.SpriteFrame} spriteFrame 60 * @param {Number} delayUnits 61 * @param {object} userInfo 62 */ 63 initWithSpriteFrame:function (spriteFrame, delayUnits, userInfo) { 64 this.setSpriteFrame(spriteFrame); 65 this.setDelayUnits(delayUnits); 66 this.setUserInfo(userInfo); 67 68 return true; 69 }, 70 71 /** 72 * cc.SpriteFrameName to be used 73 * @return {cc.SpriteFrame} 74 */ 75 getSpriteFrame:function () { 76 return this._spriteFrame; 77 }, 78 79 /** 80 * cc.SpriteFrameName to be used 81 * @param {cc.SpriteFrame} spriteFrame 82 */ 83 setSpriteFrame:function (spriteFrame) { 84 this._spriteFrame = spriteFrame; 85 }, 86 87 /** 88 * how many units of time the frame takes getter 89 * @return {Number} 90 */ 91 getDelayUnits:function () { 92 return this._delayPerUnit; 93 }, 94 95 /** 96 * how many units of time the frame takes setter 97 * @param delayUnits 98 */ 99 setDelayUnits:function (delayUnits) { 100 this._delayPerUnit = delayUnits; 101 }, 102 103 /** 104 * <p>A cc.AnimationFrameDisplayedNotification notification will be broadcasted when the frame is displayed with this dictionary as UserInfo.<br/> 105 * If UserInfo is nil, then no notification will be broadcasted. </p> 106 * @return {object} 107 */ 108 getUserInfo:function () { 109 return this._userInfo; 110 }, 111 112 /** 113 * @param {object} userInfo 114 */ 115 setUserInfo:function (userInfo) { 116 this._userInfo = userInfo; 117 } 118 }); 119 120 /** 121 * <p> 122 * A cc.Animation object is used to perform animations on the cc.Sprite objects.<br/> 123 * <br/> 124 * The cc.Animation object contains cc.SpriteFrame objects, and a possible delay between the frames. <br/> 125 * You can animate a cc.Animation object by using the cc.Animate action. Example: <br/> 126 * </p> 127 * @class 128 * @extends cc.Class 129 * 130 * @example 131 * //create an animation object 132 * var animation = cc.Animation.create(); 133 * 134 * //add a sprite frame to this animation 135 * animation.addFrameWithFile("grossini_dance_01.png"); 136 * 137 * //create an animate with this animation 138 * var action = cc.Animate.create(animation); 139 * 140 * //run animate 141 * this._grossini.runAction(action); 142 */ 143 cc.Animation = cc.Class.extend(/** @lends cc.Animation# */{ 144 _frames:null, 145 _loops:0, 146 _restoreOriginalFrame:false, 147 _duration:0, 148 _delayPerUnit:0, 149 _totalDelayUnits:0, 150 151 /** 152 * Constructor 153 */ 154 ctor:function () { 155 this._frames = []; 156 }, 157 158 // attributes 159 160 /** 161 * return array of CCAnimationFrames 162 * @return {Array} 163 */ 164 getFrames:function () { 165 return this._frames; 166 }, 167 168 /** 169 * array of CCAnimationFrames setter 170 * @param {Array} frames 171 */ 172 setFrames:function (frames) { 173 this._frames = frames; 174 }, 175 176 /** 177 * adds a frame to a cc.Animation The frame will be added with one "delay unit". 178 * @param {cc.SpriteFrame} frame 179 */ 180 addSpriteFrame:function (frame) { 181 var animFrame = new cc.AnimationFrame(); 182 183 animFrame.initWithSpriteFrame(frame, 1, null); 184 this._frames.push(animFrame); 185 // update duration 186 this._totalDelayUnits++; 187 }, 188 189 /** 190 * 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". 191 * @param {String} fileName 192 */ 193 addSpriteFrameWithFile:function (fileName) { 194 var texture = cc.TextureCache.getInstance().addImage(fileName); 195 var rect = cc.RectZero(); 196 if ((texture instanceof HTMLImageElement) || (texture instanceof HTMLCanvasElement)) { 197 rect.size = cc.size(texture.width, texture.height); 198 } else { 199 rect.size = texture.getContentSize(); 200 } 201 var frame = cc.SpriteFrame.createWithTexture(texture, rect); 202 this.addSpriteFrame(frame); 203 }, 204 205 /** 206 * 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". 207 * @param {cc.Texture2D} texture 208 * @param {cc.Rect} rect 209 */ 210 addSpriteFrameWithTexture:function (texture, rect) { 211 var pFrame = cc.SpriteFrame.createWithTexture(texture, rect); 212 this.addSpriteFrame(pFrame); 213 }, 214 215 /** 216 * Initializes a cc.Animation with cc.AnimationFrame 217 * @param {Array} arrayOfAnimationFrames 218 * @param {Number} delayPerUnit 219 * @param {Number} loops 220 */ 221 initWithAnimationFrames:function (arrayOfAnimationFrames, delayPerUnit, loops) { 222 cc.ArrayVerifyType(arrayOfAnimationFrames, cc.AnimationFrame); 223 224 this._delayPerUnit = delayPerUnit; 225 this._loops = loops; 226 227 this.setFrames([]); 228 for (var i = 0; i < arrayOfAnimationFrames.length; i++) { 229 var animFrame = arrayOfAnimationFrames[i]; 230 this._frames.push(animFrame); 231 this._totalDelayUnits += animFrame.getDelayUnits(); 232 } 233 234 return true; 235 }, 236 237 /** 238 * @param {cc.Animation} pZone 239 */ 240 copyWithZone:function (pZone) { 241 var pCopy = new cc.Animation(); 242 pCopy.initWithAnimationFrames(this._frames, this._delayPerUnit, this._loops); 243 pCopy.setRestoreOriginalFrame(this._restoreOriginalFrame); 244 return pCopy; 245 }, 246 247 copy:function (pZone) { 248 return this.copyWithZone(null); 249 }, 250 251 /** 252 * return how many times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ... 253 * @return {Number} 254 */ 255 getLoops:function () { 256 return this._loops; 257 }, 258 259 /** 260 * set how many times the animation is going to loop. 0 means animation is not animated. 1, animation is executed one time, ... 261 * @param {Number} value 262 */ 263 setLoops:function (value) { 264 this._loops = value; 265 }, 266 267 /** 268 * whether or not it shall restore the original frame when the animation finishes 269 * @param {Boolean} restOrigFrame 270 */ 271 setRestoreOriginalFrame:function (restOrigFrame) { 272 this._restoreOriginalFrame = restOrigFrame; 273 }, 274 275 /** 276 * return whether or not it shall restore the original frame when the animation finishes 277 * @return {Boolean} 278 */ 279 getRestoreOriginalFrame:function () { 280 return this._restoreOriginalFrame; 281 }, 282 283 /** 284 * return duration in seconds of the whole animation. It is the result of totalDelayUnits * delayPerUnit 285 * @return {Number} 286 */ 287 getDuration:function () { 288 return this._totalDelayUnits * this._delayPerUnit; 289 }, 290 291 /** 292 * return Delay in seconds of the "delay unit" 293 * @return {Number} 294 */ 295 getDelayPerUnit:function () { 296 return this._delayPerUnit; 297 }, 298 299 /** 300 * set Delay in seconds of the "delay unit" 301 * @param {Number} delayPerUnit 302 */ 303 setDelayPerUnit:function (delayPerUnit) { 304 this._delayPerUnit = delayPerUnit; 305 }, 306 307 /** 308 * return total Delay units of the cc.Animation. 309 * @return {Number} 310 */ 311 getTotalDelayUnits:function () { 312 return this._totalDelayUnits; 313 }, 314 315 /** 316 * Initializes a cc.Animation with frames and a delay between frames 317 * @param {Array} frames 318 * @param {Number} delay 319 */ 320 initWithSpriteFrames:function (frames, delay) { 321 cc.ArrayVerifyType(frames, cc.SpriteFrame); 322 this._loops = 1; 323 delay = delay || 0; 324 this._delayPerUnit = delay; 325 326 var tempFrames = []; 327 this.setFrames(tempFrames); 328 if (frames) { 329 for (var i = 0; i < frames.length; i++) { 330 var frame = frames[i]; 331 var animFrame = new cc.AnimationFrame(); 332 animFrame.initWithSpriteFrame(frame, 1, null); 333 this._frames.push(animFrame); 334 this._totalDelayUnits++; 335 } 336 } 337 return true; 338 } 339 }); 340 341 /** 342 * Creates an animation. 343 * @param {Array} frames 344 * @param {Number} delay 345 * @param {Number} loops 346 * @return {cc.Animation} 347 * @example 348 * //Creates an animation 349 * var animation1 = cc.Animation.create(); 350 * 351 * //Create an animation with sprite frames 352 * var animFrames = []; 353 * var frame = cache.getSpriteFrame("grossini_dance_01.png"); 354 * animFrames.push(frame); 355 * var animation2 = cc.Animation.create(animFrames); 356 * 357 * //Create an animation with sprite frames and delay 358 * var animation3 = cc.Animation.create(animFrames, 0.2); 359 */ 360 cc.Animation.create = function (frames, delay, loops) { 361 var len = arguments.length; 362 var animation = new cc.Animation(); 363 if (len == 0) { 364 animation.initWithSpriteFrames(null, 0); 365 } else if (len == 2) { 366 /** with frames and a delay between frames */ 367 delay = delay || 0; 368 animation.initWithSpriteFrames(frames, delay); 369 } else if (len == 3) { 370 animation.initWithAnimationFrames(frames, delay, loops); 371 } 372 return animation; 373 }; 374 375 /** 376 * Creates an animation with an array of cc.AnimationFrame, the delay per units in seconds and and how many times it should be executed. 377 * @param {Array} arrayOfAnimationFrameNames 378 * @param {Number} delayPerUnit 379 * @param {Number} loops 380 * @return {cc.Animation} 381 */ 382 cc.Animation.createWithAnimationFrames = function (arrayOfAnimationFrameNames, delayPerUnit, loops) { 383 var animation = new cc.Animation(); 384 animation.initWithAnimationFrames(arrayOfAnimationFrameNames, delayPerUnit, loops); 385 return animation; 386 }; 387 388