CCAction.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  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. /** Default Action tag
  23. * @constant
  24. * @type {Number}
  25. * @default
  26. */
  27. cc.ACTION_TAG_INVALID = -1;
  28. /**
  29. * Base class for cc.Action objects.
  30. * @class
  31. *
  32. * @extends cc.Class
  33. *
  34. * @property {cc.Node} target - The target will be set with the 'startWithTarget' method. When the 'stop' method is called, target will be set to nil.
  35. * @property {cc.Node} originalTarget - The original target of the action.
  36. * @property {Number} tag - The tag of the action, can be used to find the action.
  37. */
  38. cc.Action = cc.Class.extend(/** @lends cc.Action# */{
  39. //***********variables*************
  40. originalTarget:null,
  41. target:null,
  42. tag:cc.ACTION_TAG_INVALID,
  43. //**************Public Functions***********
  44. /**
  45. * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
  46. */
  47. ctor:function () {
  48. this.originalTarget = null;
  49. this.target = null;
  50. this.tag = cc.ACTION_TAG_INVALID;
  51. },
  52. /**
  53. * to copy object with deep copy.
  54. *
  55. * @deprecated since v3.0 please use .clone
  56. *
  57. * @return {cc.Action}
  58. */
  59. copy:function () {
  60. cc.log("copy is deprecated. Please use clone instead.");
  61. return this.clone();
  62. },
  63. /**
  64. * to copy object with deep copy.
  65. * returns a clone of action.
  66. *
  67. * @return {cc.Action}
  68. */
  69. clone:function () {
  70. var action = new cc.Action();
  71. action.originalTarget = null;
  72. action.target = null;
  73. action.tag = this.tag;
  74. return action;
  75. },
  76. /**
  77. * return true if the action has finished.
  78. *
  79. * @return {Boolean}
  80. */
  81. isDone:function () {
  82. return true;
  83. },
  84. /**
  85. * called before the action start. It will also set the target.
  86. *
  87. * @param {cc.Node} target
  88. */
  89. startWithTarget:function (target) {
  90. this.originalTarget = target;
  91. this.target = target;
  92. },
  93. /**
  94. * called after the action has finished. It will set the 'target' to nil. <br />
  95. * IMPORTANT: You should never call "action stop" manually. Instead, use: "target.stopAction(action);"
  96. */
  97. stop:function () {
  98. this.target = null;
  99. },
  100. /**
  101. * called every frame with it's delta time. <br />
  102. * DON'T override unless you know what you are doing.
  103. *
  104. * @param {Number} dt
  105. */
  106. step:function (dt) {
  107. cc.log("[Action step]. override me");
  108. },
  109. /**
  110. * Called once per frame. Time is the number of seconds of a frame interval.
  111. *
  112. * @param {Number} dt
  113. */
  114. update:function (dt) {
  115. cc.log("[Action update]. override me");
  116. },
  117. /**
  118. * get the target.
  119. *
  120. * @return {cc.Node}
  121. */
  122. getTarget:function () {
  123. return this.target;
  124. },
  125. /**
  126. * The action will modify the target properties.
  127. *
  128. * @param {cc.Node} target
  129. */
  130. setTarget:function (target) {
  131. this.target = target;
  132. },
  133. /**
  134. * get the original target.
  135. *
  136. * @return {cc.Node}
  137. */
  138. getOriginalTarget:function () {
  139. return this.originalTarget;
  140. },
  141. /**
  142. * Set the original target, since target can be nil. <br/>
  143. * Is the target that were used to run the action. <br/>
  144. * Unless you are doing something complex, like cc.ActionManager, you should NOT call this method. <br/>
  145. * The target is 'assigned', it is not 'retained'. <br/>
  146. * @param {cc.Node} originalTarget
  147. */
  148. setOriginalTarget:function (originalTarget) {
  149. this.originalTarget = originalTarget;
  150. },
  151. /**
  152. * get tag number.
  153. * @return {Number}
  154. */
  155. getTag:function () {
  156. return this.tag;
  157. },
  158. /**
  159. * set tag number.
  160. * @param {Number} tag
  161. */
  162. setTag:function (tag) {
  163. this.tag = tag;
  164. },
  165. /**
  166. * Currently JavaScript Bindigns (JSB), in some cases, needs to use retain and release. This is a bug in JSB, <br/>
  167. * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB. <br/>
  168. * This is a hack, and should be removed once JSB fixes the retain/release bug.
  169. */
  170. retain:function () {
  171. },
  172. /**
  173. * Currently JavaScript Bindigns (JSB), in some cases, needs to use retain and release. This is a bug in JSB, <br/>
  174. * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB. <br/>
  175. * This is a hack, and should be removed once JSB fixes the retain/release bug.
  176. */
  177. release:function () {
  178. }
  179. });
  180. /**
  181. * Allocates and initializes the action.
  182. *
  183. * @function cc.action
  184. * @static
  185. * @return {cc.Action}
  186. *
  187. * @example
  188. * // return {cc.Action}
  189. * var action = cc.action();
  190. */
  191. cc.action = function () {
  192. return new cc.Action();
  193. };
  194. /**
  195. * Please use cc.action instead. <br/>
  196. * Allocates and initializes the action.
  197. *
  198. * @deprecated since v3.0 please use cc.action() instead.
  199. * @static
  200. * @returns {cc.Action}
  201. */
  202. cc.Action.create = cc.action;
  203. /**
  204. * Base class actions that do have a finite time duration. <br/>
  205. * Possible actions: <br/>
  206. * - An action with a duration of 0 seconds. <br/>
  207. * - An action with a duration of 35.5 seconds.
  208. *
  209. * Infinite time actions are valid
  210. * @class
  211. * @extends cc.Action
  212. */
  213. cc.FiniteTimeAction = cc.Action.extend(/** @lends cc.FiniteTimeAction# */{
  214. //! duration in seconds
  215. _duration:0,
  216. /**
  217. * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
  218. */
  219. ctor:function () {
  220. cc.Action.prototype.ctor.call(this);
  221. this._duration = 0;
  222. },
  223. /**
  224. * get duration of the action. (seconds)
  225. *
  226. * @return {Number}
  227. */
  228. getDuration:function () {
  229. return this._duration * (this._times || 1);
  230. },
  231. /**
  232. * set duration of the action. (seconds)
  233. *
  234. * @param {Number} duration
  235. */
  236. setDuration:function (duration) {
  237. this._duration = duration;
  238. },
  239. /**
  240. * Returns a reversed action. <br />
  241. * For example: <br />
  242. * - The action will be x coordinates of 0 move to 100. <br />
  243. * - The reversed action will be x of 100 move to 0.
  244. * - Will be rewritten
  245. *
  246. * @return {Null}
  247. */
  248. reverse:function () {
  249. cc.log("cocos2d: FiniteTimeAction#reverse: Implement me");
  250. return null;
  251. },
  252. /**
  253. * to copy object with deep copy.
  254. * returns a clone of action.
  255. *
  256. * @return {cc.FiniteTimeAction}
  257. */
  258. clone:function () {
  259. return new cc.FiniteTimeAction();
  260. }
  261. });
  262. /**
  263. * Changes the speed of an action, making it take longer (speed > 1)
  264. * or less (speed < 1) time. <br/>
  265. * Useful to simulate 'slow motion' or 'fast forward' effect.
  266. *
  267. * @warning This action can't be Sequenceable because it is not an cc.IntervalAction
  268. * @class
  269. * @extends cc.Action
  270. * @param {cc.ActionInterval} action
  271. * @param {Number} speed
  272. */
  273. cc.Speed = cc.Action.extend(/** @lends cc.Speed# */{
  274. _speed:0.0,
  275. _innerAction:null,
  276. /**
  277. * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
  278. * @param {cc.ActionInterval} action
  279. * @param {Number} speed
  280. */
  281. ctor:function (action, speed) {
  282. cc.Action.prototype.ctor.call(this);
  283. this._speed = 0;
  284. this._innerAction = null;
  285. action && this.initWithAction(action, speed);
  286. },
  287. /**
  288. * Gets the current running speed. <br />
  289. * Will get a percentage number, compared to the original speed.
  290. *
  291. * @return {Number}
  292. */
  293. getSpeed:function () {
  294. return this._speed;
  295. },
  296. /**
  297. * alter the speed of the inner function in runtime.
  298. *
  299. * @param {Number} speed
  300. */
  301. setSpeed:function (speed) {
  302. this._speed = speed;
  303. },
  304. /**
  305. * initializes the action.
  306. *
  307. * @param {cc.ActionInterval} action
  308. * @param {Number} speed
  309. * @return {Boolean}
  310. */
  311. initWithAction:function (action, speed) {
  312. if(!action)
  313. throw "cc.Speed.initWithAction(): action must be non nil";
  314. this._innerAction = action;
  315. this._speed = speed;
  316. return true;
  317. },
  318. /**
  319. * to copy object with deep copy.
  320. * returns a clone of action.
  321. *
  322. * @returns {cc.Speed}
  323. */
  324. clone:function () {
  325. var action = new cc.Speed();
  326. action.initWithAction(this._innerAction.clone(), this._speed);
  327. return action;
  328. },
  329. /**
  330. * called before the action start. It will also set the target.
  331. *
  332. * @param {cc.Node} target
  333. */
  334. startWithTarget:function (target) {
  335. cc.Action.prototype.startWithTarget.call(this, target);
  336. this._innerAction.startWithTarget(target);
  337. },
  338. /**
  339. * Stop the action.
  340. */
  341. stop:function () {
  342. this._innerAction.stop();
  343. cc.Action.prototype.stop.call(this);
  344. },
  345. /**
  346. * called every frame with it's delta time. <br />
  347. * DON'T override unless you know what you are doing.
  348. *
  349. * @param {Number} dt
  350. */
  351. step:function (dt) {
  352. this._innerAction.step(dt * this._speed);
  353. },
  354. /**
  355. * return true if the action has finished.
  356. *
  357. * @return {Boolean}
  358. */
  359. isDone:function () {
  360. return this._innerAction.isDone();
  361. },
  362. /**
  363. * returns a reversed action. <br />
  364. * For example: <br />
  365. * - The action will be x coordinates of 0 move to 100. <br />
  366. * - The reversed action will be x of 100 move to 0.
  367. * - Will be rewritten
  368. *
  369. * @return {cc.Speed}
  370. */
  371. reverse:function () {
  372. return new cc.Speed(this._innerAction.reverse(), this._speed);
  373. },
  374. /**
  375. * Set inner Action.
  376. * @param {cc.ActionInterval} action
  377. */
  378. setInnerAction:function (action) {
  379. if (this._innerAction != action) {
  380. this._innerAction = action;
  381. }
  382. },
  383. /**
  384. * Get inner Action.
  385. *
  386. * @return {cc.ActionInterval}
  387. */
  388. getInnerAction:function () {
  389. return this._innerAction;
  390. }
  391. });
  392. /**
  393. * creates the speed action.
  394. *
  395. * @function cc.speed
  396. * @param {cc.ActionInterval} action
  397. * @param {Number} speed
  398. * @return {cc.Speed}
  399. */
  400. cc.speed = function (action, speed) {
  401. return new cc.Speed(action, speed);
  402. };
  403. /**
  404. * Please use cc.speed instead.
  405. * creates the action.
  406. *
  407. * @param {cc.ActionInterval} action
  408. * @param {Number} speed
  409. * @return {cc.Speed}
  410. * @static
  411. * @deprecated since v3.0 please use cc.speed() instead.
  412. */
  413. cc.Speed.create = cc.speed;
  414. /**
  415. * cc.Follow is an action that "follows" a node.
  416. *
  417. * @example
  418. * //example
  419. * //Instead of using cc.Camera as a "follower", use this action instead.
  420. * layer.runAction(cc.follow(hero));
  421. *
  422. * @property {Number} leftBoundary - world leftBoundary.
  423. * @property {Number} rightBoundary - world rightBoundary.
  424. * @property {Number} topBoundary - world topBoundary.
  425. * @property {Number} bottomBoundary - world bottomBoundary.
  426. *
  427. * @param {cc.Node} followedNode
  428. * @param {cc.Rect} rect
  429. * @example
  430. * // creates the action with a set boundary
  431. * var sprite = new cc.Sprite("spriteFileName");
  432. * var followAction = new cc.Follow(sprite, cc.rect(0, 0, s.width * 2 - 100, s.height));
  433. * this.runAction(followAction);
  434. *
  435. * // creates the action with no boundary set
  436. * var sprite = new cc.Sprite("spriteFileName");
  437. * var followAction = new cc.Follow(sprite);
  438. * this.runAction(followAction);
  439. *
  440. * @class
  441. * @extends cc.Action
  442. */
  443. cc.Follow = cc.Action.extend(/** @lends cc.Follow# */{
  444. // node to follow
  445. _followedNode:null,
  446. // whether camera should be limited to certain area
  447. _boundarySet:false,
  448. // if screen size is bigger than the boundary - update not needed
  449. _boundaryFullyCovered:false,
  450. // fast access to the screen dimensions
  451. _halfScreenSize:null,
  452. _fullScreenSize:null,
  453. _worldRect:null,
  454. leftBoundary:0.0,
  455. rightBoundary:0.0,
  456. topBoundary:0.0,
  457. bottomBoundary:0.0,
  458. /**
  459. * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. <br />
  460. * creates the action with a set boundary. <br/>
  461. * creates the action with no boundary set.
  462. * @param {cc.Node} followedNode
  463. * @param {cc.Rect} rect
  464. */
  465. ctor:function (followedNode, rect) {
  466. cc.Action.prototype.ctor.call(this);
  467. this._followedNode = null;
  468. this._boundarySet = false;
  469. this._boundaryFullyCovered = false;
  470. this._halfScreenSize = null;
  471. this._fullScreenSize = null;
  472. this.leftBoundary = 0.0;
  473. this.rightBoundary = 0.0;
  474. this.topBoundary = 0.0;
  475. this.bottomBoundary = 0.0;
  476. this._worldRect = cc.rect(0, 0, 0, 0);
  477. if(followedNode)
  478. rect ? this.initWithTarget(followedNode, rect)
  479. : this.initWithTarget(followedNode);
  480. },
  481. /**
  482. * to copy object with deep copy.
  483. * returns a clone of action.
  484. *
  485. * @return {cc.Follow}
  486. */
  487. clone:function () {
  488. var action = new cc.Follow();
  489. var locRect = this._worldRect;
  490. var rect = new cc.Rect(locRect.x, locRect.y, locRect.width, locRect.height);
  491. action.initWithTarget(this._followedNode, rect);
  492. return action;
  493. },
  494. /**
  495. * Get whether camera should be limited to certain area.
  496. *
  497. * @return {Boolean}
  498. */
  499. isBoundarySet:function () {
  500. return this._boundarySet;
  501. },
  502. /**
  503. * alter behavior - turn on/off boundary.
  504. *
  505. * @param {Boolean} value
  506. */
  507. setBoudarySet:function (value) {
  508. this._boundarySet = value;
  509. },
  510. /**
  511. * initializes the action with a set boundary.
  512. *
  513. * @param {cc.Node} followedNode
  514. * @param {cc.Rect} [rect=]
  515. * @return {Boolean}
  516. */
  517. initWithTarget:function (followedNode, rect) {
  518. if(!followedNode)
  519. throw "cc.Follow.initWithAction(): followedNode must be non nil";
  520. var _this = this;
  521. rect = rect || cc.rect(0, 0, 0, 0);
  522. _this._followedNode = followedNode;
  523. _this._worldRect = rect;
  524. _this._boundarySet = !cc._rectEqualToZero(rect);
  525. _this._boundaryFullyCovered = false;
  526. var winSize = cc.director.getWinSize();
  527. _this._fullScreenSize = cc.p(winSize.width, winSize.height);
  528. _this._halfScreenSize = cc.pMult(_this._fullScreenSize, 0.5);
  529. if (_this._boundarySet) {
  530. _this.leftBoundary = -((rect.x + rect.width) - _this._fullScreenSize.x);
  531. _this.rightBoundary = -rect.x;
  532. _this.topBoundary = -rect.y;
  533. _this.bottomBoundary = -((rect.y + rect.height) - _this._fullScreenSize.y);
  534. if (_this.rightBoundary < _this.leftBoundary) {
  535. // screen width is larger than world's boundary width
  536. //set both in the middle of the world
  537. _this.rightBoundary = _this.leftBoundary = (_this.leftBoundary + _this.rightBoundary) / 2;
  538. }
  539. if (_this.topBoundary < _this.bottomBoundary) {
  540. // screen width is larger than world's boundary width
  541. //set both in the middle of the world
  542. _this.topBoundary = _this.bottomBoundary = (_this.topBoundary + _this.bottomBoundary) / 2;
  543. }
  544. if ((_this.topBoundary == _this.bottomBoundary) && (_this.leftBoundary == _this.rightBoundary))
  545. _this._boundaryFullyCovered = true;
  546. }
  547. return true;
  548. },
  549. /**
  550. * called every frame with it's delta time. <br />
  551. * DON'T override unless you know what you are doing.
  552. *
  553. * @param {Number} dt
  554. */
  555. step:function (dt) {
  556. var tempPosX = this._followedNode.x;
  557. var tempPosY = this._followedNode.y;
  558. tempPosX = this._halfScreenSize.x - tempPosX;
  559. tempPosY = this._halfScreenSize.y - tempPosY;
  560. if (this._boundarySet) {
  561. // whole map fits inside a single screen, no need to modify the position - unless map boundaries are increased
  562. if (this._boundaryFullyCovered)
  563. return;
  564. this.target.setPosition(cc.clampf(tempPosX, this.leftBoundary, this.rightBoundary), cc.clampf(tempPosY, this.bottomBoundary, this.topBoundary));
  565. } else {
  566. this.target.setPosition(tempPosX, tempPosY);
  567. }
  568. },
  569. /**
  570. * Return true if the action has finished.
  571. *
  572. * @return {Boolean}
  573. */
  574. isDone:function () {
  575. return ( !this._followedNode.running );
  576. },
  577. /**
  578. * Stop the action.
  579. */
  580. stop:function () {
  581. this.target = null;
  582. cc.Action.prototype.stop.call(this);
  583. }
  584. });
  585. /**
  586. * creates the action with a set boundary. <br/>
  587. * creates the action with no boundary set.
  588. *
  589. * @function
  590. * @param {cc.Node} followedNode
  591. * @param {cc.Rect} rect
  592. * @return {cc.Follow|Null} returns the cc.Follow object on success
  593. * @example
  594. * // example
  595. * // creates the action with a set boundary
  596. * var sprite = cc.Sprite.create("spriteFileName");
  597. * var followAction = cc.follow(sprite, cc.rect(0, 0, s.width * 2 - 100, s.height));
  598. * this.runAction(followAction);
  599. *
  600. * // creates the action with no boundary set
  601. * var sprite = cc.Sprite.create("spriteFileName");
  602. * var followAction = cc.follow(sprite);
  603. * this.runAction(followAction);
  604. */
  605. cc.follow = function (followedNode, rect) {
  606. return new cc.Follow(followedNode, rect);
  607. };
  608. /**
  609. * Please use cc.follow instead.
  610. * creates the action with a set boundary. <br/>
  611. * creates the action with no boundary set.
  612. * @param {cc.Node} followedNode
  613. * @param {cc.Rect} rect
  614. * @return {cc.Follow|Null} returns the cc.Follow object on success
  615. * @static
  616. * @deprecated since v3.0 please cc.follow() instead.
  617. */
  618. cc.Follow.create = cc.follow;