CCAnimation.js 15 KB

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