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> An interval action is an action that takes place within a certain period of time. <br/> 29 * It has an start time, and a finish time. The finish time is the parameter<br/> 30 * duration plus the start time.</p> 31 * 32 * <p>These CCActionInterval actions have some interesting properties, like:<br/> 33 * - They can run normally (default) <br/> 34 * - They can run reversed with the reverse method <br/> 35 * - They can run with the time altered with the Accelerate, AccelDeccel and Speed actions. </p> 36 * 37 * <p>For example, you can simulate a Ping Pong effect running the action normally and<br/> 38 * then running it again in Reverse mode. </p> 39 * 40 * @class 41 * @extends cc.FiniteTimeAction 42 * @Example 43 * // example 44 * var pingPongAction = cc.Sequence.create(action, action.reverse()); 45 */ 46 cc.ActionInterval = cc.FiniteTimeAction.extend(/** @lends cc.ActionInterval# */{ 47 _elapsed:0, 48 _firstTick:false, 49 50 /** 51 * @constructor 52 * @param {Number} d duration in seconds 53 * @example 54 * var actionInterval = new cc.ActionInterval(3); 55 */ 56 ctor:function (d) { 57 cc.FiniteTimeAction.prototype.ctor.call(this); 58 59 d !== undefined && this.initWithDuration(d); 60 }, 61 62 /** how many seconds had elapsed since the actions started to run. 63 * @return {Number} 64 */ 65 getElapsed:function () { 66 return this._elapsed; 67 }, 68 69 /** initializes the action 70 * @param {Number} d duration in seconds 71 * @return {Boolean} 72 */ 73 initWithDuration:function (d) { 74 this._duration = (d === 0) ? cc.FLT_EPSILON : d; 75 // prevent division by 0 76 // This comparison could be in step:, but it might decrease the performance 77 // by 3% in heavy based action games. 78 this._elapsed = 0; 79 this._firstTick = true; 80 return true; 81 }, 82 83 /** returns true if the action has finished 84 * @return {Boolean} 85 */ 86 isDone:function () { 87 return (this._elapsed >= this._duration); 88 }, 89 90 /** 91 * returns a new clone of the action 92 * @returns {cc.ActionInterval} 93 */ 94 clone:function () { 95 return new cc.ActionInterval(this._duration); 96 }, 97 98 /** 99 * @param {Number} dt delta time in seconds 100 */ 101 step:function (dt) { 102 if (this._firstTick) { 103 this._firstTick = false; 104 this._elapsed = 0; 105 } else 106 this._elapsed += dt; 107 108 //this.update((1 > (this._elapsed / this._duration)) ? this._elapsed / this._duration : 1); 109 //this.update(Math.max(0, Math.min(1, this._elapsed / Math.max(this._duration, cc.FLT_EPSILON)))); 110 var t = this._elapsed / (this._duration > 0.0000001192092896 ? this._duration : 0.0000001192092896); 111 t = (1 > t ? t : 1); 112 this.update(t > 0 ? t : 0); 113 }, 114 115 /** 116 * @param {cc.Node} target 117 */ 118 startWithTarget:function (target) { 119 cc.Action.prototype.startWithTarget.call(this, target); 120 this._elapsed = 0; 121 this._firstTick = true; 122 }, 123 124 /** 125 * @return {Null} 126 */ 127 reverse:function () { 128 cc.log("cc.IntervalAction: reverse not implemented."); 129 return null; 130 }, 131 132 /** 133 * @param {Number} amp 134 */ 135 setAmplitudeRate:function (amp) { 136 // Abstract class needs implementation 137 cc.log("cc.ActionInterval.setAmplitudeRate(): it should be overridden in subclass."); 138 }, 139 140 /** 141 * @return {Number} 142 */ 143 getAmplitudeRate:function () { 144 // Abstract class needs implementation 145 cc.log("cc.ActionInterval.getAmplitudeRate(): it should be overridden in subclass."); 146 } 147 }); 148 149 /** 150 * @param {Number} d duration in seconds 151 * @return {cc.ActionInterval} 152 * @example 153 * // example 154 * var actionInterval = cc.ActionInterval.create(3); 155 */ 156 cc.ActionInterval.create = function (d) { 157 return new cc.ActionInterval(d); 158 }; 159 160 161 /** Runs actions sequentially, one after another 162 * @class 163 * @extends cc.ActionInterval 164 */ 165 cc.Sequence = cc.ActionInterval.extend(/** @lends cc.Sequence# */{ 166 _actions:null, 167 _split:null, 168 _last:0, 169 170 /** Create an array of sequenceable actions 171 * @constructor 172 * @param {Array|cc.FiniteTimeAction} tempArray 173 * @return {cc.Sequence} 174 * @example 175 * // create sequence with actions 176 * var seq = new cc.Sequence(act1, act2); 177 * 178 * // create sequence with array 179 * var seq = new cc.Sequence(actArray); 180 */ 181 ctor:function (tempArray) { 182 cc.ActionInterval.prototype.ctor.call(this); 183 this._actions = []; 184 185 var paramArray = (tempArray instanceof Array) ? tempArray : arguments; 186 var last = paramArray.length - 1; 187 if ((last >= 0) && (paramArray[last] == null)) 188 cc.log("parameters should not be ending with null in Javascript"); 189 190 if (last >= 0) { 191 var prev = paramArray[0], action1; 192 for (var i = 1; i < last; i++) { 193 if (paramArray[i]) { 194 action1 = prev; 195 prev = cc.Sequence.create(); 196 prev.initWithTwoActions(action1, paramArray[i]); 197 } 198 } 199 this.initWithTwoActions(prev, paramArray[last]); 200 } 201 }, 202 203 /** initializes the action <br/> 204 * @param {cc.FiniteTimeAction} actionOne 205 * @param {cc.FiniteTimeAction} actionTwo 206 * @return {Boolean} 207 */ 208 initWithTwoActions:function (actionOne, actionTwo) { 209 if(!actionOne || !actionTwo) 210 throw "cc.Sequence.initWithTwoActions(): arguments must all be non nil"; 211 212 var d = actionOne.getDuration() + actionTwo.getDuration(); 213 this.initWithDuration(d); 214 215 this._actions[0] = actionOne; 216 this._actions[1] = actionTwo; 217 return true; 218 }, 219 220 /** 221 * returns a new clone of the action 222 * @returns {cc.Sequence} 223 */ 224 clone:function () { 225 var action = new cc.Sequence(); 226 action.initWithTwoActions(this._actions[0].clone(), this._actions[1].clone()); 227 return action; 228 }, 229 230 /** 231 * @param {cc.Node} target 232 */ 233 startWithTarget:function (target) { 234 cc.ActionInterval.prototype.startWithTarget.call(this, target); 235 this._split = this._actions[0].getDuration() / this._duration; 236 this._last = -1; 237 }, 238 239 /** 240 * stop the action 241 */ 242 stop:function () { 243 // Issue #1305 244 if (this._last !== -1) 245 this._actions[this._last].stop(); 246 cc.Action.prototype.stop.call(this); 247 }, 248 249 /** 250 * @param {Number} time time in seconds 251 */ 252 update:function (time) { 253 var new_t, found = 0; 254 var locSplit = this._split, locActions = this._actions, locLast = this._last; 255 if (time < locSplit) { 256 // action[0] 257 new_t = (locSplit !== 0) ? time / locSplit : 1; 258 259 if (found === 0 && locLast === 1) { 260 // Reverse mode ? 261 // XXX: Bug. this case doesn't contemplate when _last==-1, found=0 and in "reverse mode" 262 // since it will require a hack to know if an action is on reverse mode or not. 263 // "step" should be overriden, and the "reverseMode" value propagated to inner Sequences. 264 locActions[1].update(0); 265 locActions[1].stop(); 266 } 267 } else { 268 // action[1] 269 found = 1; 270 new_t = (locSplit === 1) ? 1 : (time - locSplit) / (1 - locSplit); 271 272 if (locLast === -1) { 273 // action[0] was skipped, execute it. 274 locActions[0].startWithTarget(this.target); 275 locActions[0].update(1); 276 locActions[0].stop(); 277 } 278 if (!locLast) { 279 // switching to action 1. stop action 0. 280 locActions[0].update(1); 281 locActions[0].stop(); 282 } 283 } 284 285 // Last action found and it is done. 286 if (locLast === found && locActions[found].isDone()) 287 return; 288 289 // Last action found and it is done 290 if (locLast !== found) 291 locActions[found].startWithTarget(this.target); 292 293 locActions[found].update(new_t); 294 this._last = found; 295 }, 296 297 /** 298 * @return {cc.ActionInterval} 299 */ 300 reverse:function () { 301 return cc.Sequence._actionOneTwo(this._actions[1].reverse(), this._actions[0].reverse()); 302 }, 303 304 /** 305 * to copy object with deep copy. 306 * @return {object} 307 */ 308 copy:function () { 309 return this.clone(); 310 } 311 }); 312 /** helper constructor to create an array of sequenceable actions 313 * @param {Array|cc.FiniteTimeAction} tempArray 314 * @return {cc.Sequence} 315 * @example 316 * // example 317 * // create sequence with actions 318 * var seq = cc.Sequence.create(act1, act2); 319 * 320 * // create sequence with array 321 * var seq = cc.Sequence.create(actArray); 322 */ 323 cc.Sequence.create = function (/*Multiple Arguments*/tempArray) { 324 var paramArray = (tempArray instanceof Array) ? tempArray : arguments; 325 if ((paramArray.length > 0) && (paramArray[paramArray.length - 1] == null)) 326 cc.log("parameters should not be ending with null in Javascript"); 327 328 var prev = paramArray[0]; 329 for (var i = 1; i < paramArray.length; i++) { 330 if (paramArray[i]) 331 prev = cc.Sequence._actionOneTwo(prev, paramArray[i]); 332 } 333 return prev; 334 }; 335 336 /** creates the action 337 * @param {cc.FiniteTimeAction} actionOne 338 * @param {cc.FiniteTimeAction} actionTwo 339 * @return {cc.Sequence} 340 * @private 341 */ 342 cc.Sequence._actionOneTwo = function (actionOne, actionTwo) { 343 var sequence = new cc.Sequence(); 344 sequence.initWithTwoActions(actionOne, actionTwo); 345 return sequence; 346 }; 347 348 349 /** 350 * Repeats an action a number of times. 351 * To repeat an action forever use the CCRepeatForever action. 352 * @class 353 * @extends cc.ActionInterval 354 */ 355 cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{ 356 _times:0, 357 _total:0, 358 _nextDt:0, 359 _actionInstant:false, 360 _innerAction:null, //CCFiniteTimeAction 361 362 /** 363 * Creates a Repeat action. Times is an unsigned integer between 1 and pow(2,30) 364 * @constructor 365 * @param {cc.FiniteTimeAction} action 366 * @param {Number} times 367 * @example 368 * var rep = new cc.Repeat(cc.Sequence.create(jump2, jump1), 5); 369 */ 370 ctor: function (action, times) { 371 cc.ActionInterval.prototype.ctor.call(this); 372 373 times !== undefined && this.initWithAction(action, times); 374 }, 375 376 /** 377 * @param {cc.FiniteTimeAction} action 378 * @param {Number} times 379 * @return {Boolean} 380 */ 381 initWithAction:function (action, times) { 382 var duration = action.getDuration() * times; 383 384 if (this.initWithDuration(duration)) { 385 this._times = times; 386 this._innerAction = action; 387 if (action instanceof cc.ActionInstant) 388 this._times -= 1; 389 this._total = 0; 390 return true; 391 } 392 return false; 393 }, 394 395 /** 396 * returns a new clone of the action 397 * @returns {cc.Repeat} 398 */ 399 clone:function () { 400 var action = new cc.Repeat(); 401 action.initWithAction(this._innerAction.clone(), this._times); 402 return action; 403 }, 404 405 /** 406 * @param {cc.Node} target 407 */ 408 startWithTarget:function (target) { 409 this._total = 0; 410 this._nextDt = this._innerAction.getDuration() / this._duration; 411 cc.ActionInterval.prototype.startWithTarget.call(this, target); 412 this._innerAction.startWithTarget(target); 413 }, 414 415 /** 416 * stop the action 417 */ 418 stop:function () { 419 this._innerAction.stop(); 420 cc.Action.prototype.stop.call(this); 421 }, 422 423 /** 424 * @param {Number} time time in seconds 425 */ 426 update:function (time) { 427 var locInnerAction = this._innerAction; 428 var locDuration = this._duration; 429 var locTimes = this._times; 430 var locNextDt = this._nextDt; 431 432 if (time >= locNextDt) { 433 while (time > locNextDt && this._total < locTimes) { 434 locInnerAction.update(1); 435 this._total++; 436 locInnerAction.stop(); 437 locInnerAction.startWithTarget(this.target); 438 locNextDt += locInnerAction.getDuration() / locDuration; 439 this._nextDt = locNextDt; 440 } 441 442 // fix for issue #1288, incorrect end value of repeat 443 if (time >= 1.0 && this._total < locTimes) 444 this._total++; 445 446 // don't set a instantaction back or update it, it has no use because it has no duration 447 if (this._actionInstant) { 448 if (this._total == locTimes) { 449 locInnerAction.update(1); 450 locInnerAction.stop(); 451 } else { 452 // issue #390 prevent jerk, use right update 453 locInnerAction.update(time - (locNextDt - locInnerAction.getDuration() / locDuration)); 454 } 455 } 456 } else { 457 locInnerAction.update((time * locTimes) % 1.0); 458 } 459 }, 460 461 /** 462 * @return {Boolean} 463 */ 464 isDone:function () { 465 return this._total == this._times; 466 }, 467 468 /** 469 * @return {cc.ActionInterval} 470 */ 471 reverse:function () { 472 return cc.Repeat.create(this._innerAction.reverse(), this._times); 473 }, 474 475 /** 476 * @param {cc.FiniteTimeAction} action 477 */ 478 setInnerAction:function (action) { 479 if (this._innerAction != action) { 480 this._innerAction = action; 481 } 482 }, 483 484 /** 485 * @return {cc.FiniteTimeAction} 486 */ 487 getInnerAction:function () { 488 return this._innerAction; 489 } 490 }); 491 /** 492 * Creates a Repeat action. Times is an unsigned integer between 1 and pow(2,30) 493 * @param {cc.FiniteTimeAction} action 494 * @param {Number} times 495 * @return {cc.Repeat} 496 * @example 497 * // example 498 * var rep = cc.Repeat.create(cc.Sequence.create(jump2, jump1), 5); 499 */ 500 cc.Repeat.create = function (action, times) { 501 return new cc.Repeat(action, times); 502 }; 503 504 505 /** Repeats an action for ever. <br/> 506 * To repeat the an action for a limited number of times use the Repeat action. <br/> 507 * @warning This action can't be Sequencable because it is not an IntervalAction 508 * @class 509 * @extends cc.ActionInterval 510 */ 511 512 cc.RepeatForever = cc.ActionInterval.extend(/** @lends cc.RepeatForever# */{ 513 _innerAction:null, //CCActionInterval 514 515 /** 516 * Create a acton which repeat forever 517 * @param {cc.FiniteTimeAction} action 518 * @example 519 * var repeat = new cc.RepeatForever(cc.RotateBy.create(1.0, 360)); 520 */ 521 ctor:function (action) { 522 cc.ActionInterval.prototype.ctor.call(this); 523 this._innerAction = null; 524 525 action && this.initWithAction(action); 526 }, 527 528 /** 529 * @param {cc.ActionInterval} action 530 * @return {Boolean} 531 */ 532 initWithAction:function (action) { 533 if(!action) 534 throw "cc.RepeatForever.initWithAction(): action must be non null"; 535 536 this._innerAction = action; 537 return true; 538 }, 539 540 /** 541 * returns a new clone of the action 542 * @returns {cc.RepeatForever} 543 */ 544 clone:function () { 545 var action = new cc.RepeatForever(); 546 action.initWithAction(this._innerAction.clone()); 547 return action; 548 }, 549 550 /** 551 * @param {cc.Node} target 552 */ 553 startWithTarget:function (target) { 554 cc.ActionInterval.prototype.startWithTarget.call(this, target); 555 this._innerAction.startWithTarget(target); 556 }, 557 558 /** 559 * @param dt delta time in seconds 560 */ 561 step:function (dt) { 562 var locInnerAction = this._innerAction; 563 locInnerAction.step(dt); 564 if (locInnerAction.isDone()) { 565 //var diff = locInnerAction.getElapsed() - locInnerAction.getDuration(); 566 locInnerAction.startWithTarget(this.target); 567 // to prevent jerk. issue #390 ,1247 568 //this._innerAction.step(0); 569 //this._innerAction.step(diff); 570 locInnerAction.step(locInnerAction.getElapsed() - locInnerAction.getDuration()); 571 } 572 }, 573 574 /** 575 * @return {Boolean} 576 */ 577 isDone:function () { 578 return false; 579 }, 580 581 /** 582 * @return {cc.ActionInterval} 583 */ 584 reverse:function () { 585 return (cc.RepeatForever.create(this._innerAction.reverse())); 586 }, 587 588 /** 589 * 590 * @param {cc.ActionInterval} action 591 */ 592 setInnerAction:function (action) { 593 if (this._innerAction != action) { 594 this._innerAction = action; 595 } 596 }, 597 598 /** 599 * @return {cc.ActionInterval} 600 */ 601 getInnerAction:function () { 602 return this._innerAction; 603 } 604 }); 605 /** 606 * Create a acton which repeat forever 607 * @param {cc.FiniteTimeAction} action 608 * @return {cc.RepeatForever} 609 * @example 610 * // example 611 * var repeat = cc.RepeatForever.create(cc.RotateBy.create(1.0, 360)); 612 */ 613 cc.RepeatForever.create = function (action) { 614 return new cc.RepeatForever(action); 615 }; 616 617 618 /** Spawn a new action immediately 619 * @class 620 * @extends cc.ActionInterval 621 */ 622 cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{ 623 _one:null, 624 _two:null, 625 626 /** 627 * @constructor 628 * @param {Array|cc.FiniteTimeAction} tempArray 629 * @example 630 * var action = new cc.Spawn(cc.JumpBy.create(2, cc.p(300, 0), 50, 4), cc.RotateBy.create(2, 720)); 631 */ 632 ctor:function (tempArray) { 633 cc.ActionInterval.prototype.ctor.call(this); 634 this._one = null; 635 this._two = null; 636 637 var paramArray = (tempArray instanceof Array) ? tempArray : arguments; 638 var last = paramArray.length - 1; 639 if ((last >= 0) && (paramArray[last] == null)) 640 cc.log("parameters should not be ending with null in Javascript"); 641 642 if (last >= 0) { 643 var prev = paramArray[0], action1; 644 for (var i = 1; i < last; i++) { 645 if (paramArray[i]) { 646 action1 = prev; 647 prev = cc.Spwan.create(); 648 prev.initWithTwoActions(action1, paramArray[i]); 649 } 650 } 651 this.initWithTwoActions(prev, paramArray[last]); 652 } 653 }, 654 655 /** initializes the Spawn action with the 2 actions to spawn 656 * @param {cc.FiniteTimeAction} action1 657 * @param {cc.FiniteTimeAction} action2 658 * @return {Boolean} 659 */ 660 initWithTwoActions:function (action1, action2) { 661 if(!action1 || !action2) 662 throw "cc.Spawn.initWithTwoActions(): arguments must all be non null" ; 663 664 var ret = false; 665 666 var d1 = action1.getDuration(); 667 var d2 = action2.getDuration(); 668 669 if (this.initWithDuration(Math.max(d1, d2))) { 670 this._one = action1; 671 this._two = action2; 672 673 if (d1 > d2) { 674 this._two = cc.Sequence._actionOneTwo(action2, cc.DelayTime.create(d1 - d2)); 675 } else if (d1 < d2) { 676 this._one = cc.Sequence._actionOneTwo(action1, cc.DelayTime.create(d2 - d1)); 677 } 678 679 ret = true; 680 } 681 return ret; 682 }, 683 684 /** 685 * returns a new clone of the action 686 * @returns {cc.Spawn} 687 */ 688 clone:function () { 689 var action = new cc.Spawn(); 690 action.initWithTwoActions(this._one.clone(), this._two.clone()); 691 return action; 692 }, 693 694 /** 695 * @param {cc.Node} target 696 */ 697 startWithTarget:function (target) { 698 cc.ActionInterval.prototype.startWithTarget.call(this, target); 699 this._one.startWithTarget(target); 700 this._two.startWithTarget(target); 701 }, 702 703 /** 704 * Stop the action 705 */ 706 stop:function () { 707 this._one.stop(); 708 this._two.stop(); 709 cc.Action.prototype.stop.call(this); 710 }, 711 712 /** 713 * @param {Number} time time in seconds 714 */ 715 update:function (time) { 716 if (this._one) 717 this._one.update(time); 718 if (this._two) 719 this._two.update(time); 720 }, 721 722 /** 723 * @return {cc.FiniteTimeAction} 724 */ 725 reverse:function () { 726 return cc.Spawn._actionOneTwo(this._one.reverse(), this._two.reverse()); 727 } 728 }); 729 730 /** 731 * @param {Array|cc.FiniteTimeAction}tempArray 732 * @return {cc.FiniteTimeAction} 733 * @example 734 * // example 735 * var action = cc.Spawn.create(cc.JumpBy.create(2, cc.p(300, 0), 50, 4), cc.RotateBy.create(2, 720)); 736 */ 737 cc.Spawn.create = function (/*Multiple Arguments*/tempArray) { 738 var paramArray = (tempArray instanceof Array) ? tempArray : arguments; 739 if ((paramArray.length > 0) && (paramArray[paramArray.length - 1] == null)) 740 cc.log("parameters should not be ending with null in Javascript"); 741 742 var prev = paramArray[0]; 743 for (var i = 1; i < paramArray.length; i++) { 744 if (paramArray[i] != null) 745 prev = this._actionOneTwo(prev, paramArray[i]); 746 } 747 return prev; 748 }; 749 750 /** 751 * @param {cc.FiniteTimeAction} action1 752 * @param {cc.FiniteTimeAction} action2 753 * @return {cc.Spawn} 754 * @private 755 */ 756 cc.Spawn._actionOneTwo = function (action1, action2) { 757 var pSpawn = new cc.Spawn(); 758 pSpawn.initWithTwoActions(action1, action2); 759 return pSpawn; 760 }; 761 762 763 /** Rotates a cc.Node object to a certain angle by modifying it's 764 * rotation attribute. <br/> 765 * The direction will be decided by the shortest angle. 766 * @class 767 * @extends cc.ActionInterval 768 */ 769 cc.RotateTo = cc.ActionInterval.extend(/** @lends cc.RotateTo# */{ 770 _dstAngleX:0, 771 _startAngleX:0, 772 _diffAngleX:0, 773 774 _dstAngleY:0, 775 _startAngleY:0, 776 _diffAngleY:0, 777 778 /** 779 * Creates a RotateTo action with x and y rotation angles 780 * @constructor 781 * @param {Number} duration duration in seconds 782 * @param {Number} deltaAngleX deltaAngleX in degrees. 783 * @param {Number} [deltaAngleY] deltaAngleY in degrees. 784 * @example 785 * var rotateTo = new cc.RotateTo(2, 61.0); 786 */ 787 ctor:function (duration, deltaAngleX, deltaAngleY) { 788 cc.ActionInterval.prototype.ctor.call(this); 789 790 deltaAngleX !== undefined && this.initWithDuration(duration, deltaAngleX, deltaAngleY); 791 }, 792 793 /** 794 * @param {Number} duration 795 * @param {Number} deltaAngleX 796 * @param {Number} deltaAngleY 797 * @return {Boolean} 798 */ 799 initWithDuration:function (duration, deltaAngleX, deltaAngleY) { 800 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 801 this._dstAngleX = deltaAngleX || 0; 802 this._dstAngleY = deltaAngleY || this._dstAngleX; 803 return true; 804 } 805 return false; 806 }, 807 808 /** 809 * returns a new clone of the action 810 * @returns {cc.RotateTo} 811 */ 812 clone:function () { 813 var action = new cc.RotateTo(); 814 action.initWithDuration(this._duration, this._dstAngleX, this._dstAngleY); 815 return action; 816 }, 817 818 /** 819 * @param {cc.Node} target 820 */ 821 startWithTarget:function (target) { 822 cc.ActionInterval.prototype.startWithTarget.call(this, target); 823 824 // Calculate X 825 var locStartAngleX = target.rotationX % 360.0; 826 var locDiffAngleX = this._dstAngleX - locStartAngleX; 827 if (locDiffAngleX > 180) 828 locDiffAngleX -= 360; 829 if (locDiffAngleX < -180) 830 locDiffAngleX += 360; 831 this._startAngleX = locStartAngleX; 832 this._diffAngleX = locDiffAngleX; 833 834 // Calculate Y It's duplicated from calculating X since the rotation wrap should be the same 835 this._startAngleY = target.rotationY % 360.0; 836 var locDiffAngleY = this._dstAngleY - this._startAngleY; 837 if (locDiffAngleY > 180) 838 locDiffAngleY -= 360; 839 if (locDiffAngleY < -180) 840 locDiffAngleY += 360; 841 this._diffAngleY = locDiffAngleY; 842 }, 843 844 /** 845 * RotateTo reverse not implemented 846 */ 847 reverse:function () { 848 cc.log("cc.RotateTo.reverse(): it should be overridden in subclass."); 849 }, 850 851 /** 852 * @param {Number} time time in seconds 853 */ 854 update:function (time) { 855 if (this.target) { 856 this.target.rotationX = this._startAngleX + this._diffAngleX * time; 857 this.target.rotationY = this._startAngleY + this._diffAngleY * time; 858 } 859 } 860 }); 861 862 /** 863 * Creates a RotateTo action with separate rotation angles 864 * @param {Number} duration duration in seconds 865 * @param {Number} deltaAngleX deltaAngleX in degrees. 866 * @param {Number} [deltaAngleY] deltaAngleY in degrees. 867 * @return {cc.RotateTo} 868 * @example 869 * // example 870 * var rotateTo = cc.RotateTo.create(2, 61.0); 871 */ 872 cc.RotateTo.create = function (duration, deltaAngleX, deltaAngleY) { 873 return new cc.RotateTo(duration, deltaAngleX, deltaAngleY); 874 }; 875 876 877 /** Rotates a cc.Node object clockwise a number of degrees by modifying it's rotation attribute. 878 * @class 879 * @extends cc.ActionInterval 880 */ 881 cc.RotateBy = cc.ActionInterval.extend(/** @lends cc.RotateBy# */{ 882 _angleX:0, 883 _startAngleX:0, 884 _angleY:0, 885 _startAngleY:0, 886 887 /** 888 * @constructor 889 * @param {Number} duration druation in seconds 890 * @param {Number} deltaAngleX deltaAngleX in degrees 891 * @param {Number} [deltaAngleY] deltaAngleY in degrees 892 * @example 893 * var actionBy = new cc.RotateBy(2, 360); 894 */ 895 ctor: function (duration, deltaAngleX, deltaAngleY) { 896 cc.ActionInterval.prototype.ctor.call(this); 897 898 deltaAngleX !== undefined && this.initWithDuration(duration, deltaAngleX, deltaAngleY); 899 }, 900 901 /** 902 * @param {Number} duration duration in seconds 903 * @param {Number} deltaAngleX deltaAngleX in degrees 904 * @param {Number} [deltaAngleY=] deltaAngleY in degrees 905 * @return {Boolean} 906 */ 907 initWithDuration:function (duration, deltaAngleX, deltaAngleY) { 908 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 909 this._angleX = deltaAngleX || 0; 910 this._angleY = deltaAngleY || this._angleX; 911 return true; 912 } 913 return false; 914 }, 915 916 /** 917 * returns a new clone of the action 918 * @returns {cc.RotateBy} 919 */ 920 clone:function () { 921 var action = new cc.RotateBy(); 922 action.initWithDuration(this._duration, this._angleX, this._angleY); 923 return action; 924 }, 925 926 /** 927 * @param {cc.Node} target 928 */ 929 startWithTarget:function (target) { 930 cc.ActionInterval.prototype.startWithTarget.call(this, target); 931 this._startAngleX = target.rotationX; 932 this._startAngleY = target.rotationY; 933 }, 934 935 /** 936 * @param {Number} time 937 */ 938 update:function (time) { 939 if (this.target) { 940 this.target.rotationX = this._startAngleX + this._angleX * time; 941 this.target.rotationY = this._startAngleY + this._angleY * time; 942 } 943 }, 944 945 /** 946 * @return {cc.ActionInterval} 947 */ 948 reverse:function () { 949 return cc.RotateBy.create(this._duration, -this._angleX, -this._angleY); 950 } 951 }); 952 953 /** 954 * @param {Number} duration druation in seconds 955 * @param {Number} deltaAngleX deltaAngleX in degrees 956 * @param {Number} [deltaAngleY] deltaAngleY in degrees 957 * @return {cc.RotateBy} 958 * @example 959 * // example 960 * var actionBy = cc.RotateBy.create(2, 360); 961 */ 962 cc.RotateBy.create = function (duration, deltaAngleX, deltaAngleY) { 963 var rotateBy = new cc.RotateBy(); 964 rotateBy.initWithDuration(duration, deltaAngleX, deltaAngleY); 965 return rotateBy; 966 }; 967 968 969 /** 970 * <p> 971 * Moves a CCNode object x,y pixels by modifying it's position attribute. <br/> 972 * x and y are relative to the position of the object. <br/> 973 * Several CCMoveBy actions can be concurrently called, and the resulting <br/> 974 * movement will be the sum of individual movements. 975 * </p> 976 * @class 977 * @extends cc.ActionInterval 978 */ 979 cc.MoveBy = cc.ActionInterval.extend(/** @lends cc.MoveBy# */{ 980 _positionDelta:null, 981 _startPosition:null, 982 _previousPosition:null, 983 984 /** 985 * @constructor 986 * @param {Number} duration duration in seconds 987 * @param {cc.Point|Number} deltaPos 988 * @param {Number} [deltaY] 989 * @example 990 * var actionTo = cc.MoveBy.create(2, cc.p(windowSize.width - 40, windowSize.height - 40)); 991 */ 992 ctor:function (duration, deltaPos, deltaY) { 993 cc.ActionInterval.prototype.ctor.call(this); 994 995 this._positionDelta = cc.p(0, 0); 996 this._startPosition = cc.p(0, 0); 997 this._previousPosition = cc.p(0, 0); 998 999 deltaPos !== undefined && this.initWithDuration(duration, deltaPos, deltaY); 1000 }, 1001 1002 /** 1003 * @param {Number} duration duration in seconds 1004 * @param {cc.Point} position 1005 * @param {Number} [y] 1006 * @return {Boolean} 1007 */ 1008 initWithDuration:function (duration, position, y) { 1009 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 1010 if(position.x !== undefined) { 1011 y = position.y; 1012 position = position.x; 1013 } 1014 1015 this._positionDelta.x = position; 1016 this._positionDelta.y = y; 1017 return true; 1018 } 1019 return false; 1020 }, 1021 1022 /** 1023 * returns a new clone of the action 1024 * @returns {cc.MoveBy} 1025 */ 1026 clone:function () { 1027 var action = new cc.MoveBy(); 1028 action.initWithDuration(this._duration, this._positionDelta) 1029 return action; 1030 }, 1031 1032 /** 1033 * @param {Number} target 1034 */ 1035 startWithTarget:function (target) { 1036 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1037 var locPosX = target.getPositionX(); 1038 var locPosY = target.getPositionY(); 1039 this._previousPosition.x = locPosX; 1040 this._previousPosition.y = locPosY; 1041 this._startPosition.x = locPosX; 1042 this._startPosition.y = locPosY; 1043 }, 1044 1045 /** 1046 * @param {Number} time time in seconds 1047 */ 1048 update:function (time) { 1049 if (this.target) { 1050 var x = this._positionDelta.x * time; 1051 var y = this._positionDelta.y * time; 1052 var locStartPosition = this._startPosition; 1053 if (cc.ENABLE_STACKABLE_ACTIONS) { 1054 var targetX = this.target.getPositionX(); 1055 var targetY = this.target.getPositionY(); 1056 var locPreviousPosition = this._previousPosition; 1057 1058 locStartPosition.x = locStartPosition.x + targetX - locPreviousPosition.x; 1059 locStartPosition.y = locStartPosition.y + targetY - locPreviousPosition.y; 1060 x = x + locStartPosition.x; 1061 y = y + locStartPosition.y; 1062 locPreviousPosition.x = x; 1063 locPreviousPosition.y = y; 1064 this.target.setPosition(x, y); 1065 } else { 1066 this.target.setPosition(locStartPosition.x + x, locStartPosition.y + y); 1067 } 1068 } 1069 }, 1070 1071 /** 1072 * MoveTo reverse is not implemented 1073 */ 1074 reverse:function () { 1075 return cc.MoveBy.create(this._duration, cc.p(-this._positionDelta.x, -this._positionDelta.y)); 1076 } 1077 }); 1078 1079 /** 1080 * @param {Number} duration duration in seconds 1081 * @param {cc.Point|Number} deltaPosition 1082 * @param {Number} deltaY 1083 * @return {cc.MoveBy} 1084 * @example 1085 * // example 1086 * var actionTo = cc.MoveBy.create(2, cc.p(windowSize.width - 40, windowSize.height - 40)); 1087 */ 1088 cc.MoveBy.create = function (duration, deltaPos, deltaY) { 1089 return new cc.MoveBy(duration, deltaPos, deltaY); 1090 }; 1091 1092 1093 /** 1094 * Moves a CCNode object to the position x,y. x and y are absolute coordinates by modifying it's position attribute. <br/> 1095 * Several CCMoveTo actions can be concurrently called, and the resulting <br/> 1096 * movement will be the sum of individual movements. 1097 * @class 1098 * @extends cc.MoveBy 1099 */ 1100 cc.MoveTo = cc.MoveBy.extend(/** @lends cc.MoveTo# */{ 1101 _endPosition:null, 1102 1103 /** 1104 * @constructor 1105 * @param {Number} duration duration in seconds 1106 * @param {cc.Point|Number} position 1107 * @param {Number} y 1108 * @example 1109 * var actionBy = cc.MoveTo.create(2, cc.p(80, 80)); 1110 */ 1111 ctor:function (duration, position, y) { 1112 cc.MoveBy.prototype.ctor.call(this); 1113 this._endPosition = cc.p(0, 0); 1114 1115 position !== undefined && this.initWithDuration(duration, position, y); 1116 }, 1117 1118 /** 1119 * @param {Number} duration duration in seconds 1120 * @param {cc.Point} position 1121 * @param {Number} y 1122 * @return {Boolean} 1123 */ 1124 initWithDuration:function (duration, position, y) { 1125 if (cc.MoveBy.prototype.initWithDuration.call(this, duration, position, y)) { 1126 if(position.x !== undefined) { 1127 y = position.y; 1128 position = position.x; 1129 } 1130 1131 this._endPosition.x = position; 1132 this._endPosition.y = y; 1133 return true; 1134 } 1135 return false; 1136 }, 1137 1138 /** 1139 * returns a new clone of the action 1140 * @returns {cc.MoveTo} 1141 */ 1142 clone:function () { 1143 var action = new cc.MoveTo(); 1144 action.initWithDuration(this._duration, this._endPosition); 1145 return action; 1146 }, 1147 1148 /** 1149 * @param {cc.Node} target 1150 */ 1151 startWithTarget:function (target) { 1152 cc.MoveBy.prototype.startWithTarget.call(this, target); 1153 this._positionDelta.x = this._endPosition.x - target.getPositionX(); 1154 this._positionDelta.y = this._endPosition.y - target.getPositionY(); 1155 } 1156 }); 1157 /** 1158 * @param {Number} duration duration in seconds 1159 * @param {cc.Point} position 1160 * @param {Number} y 1161 * @return {cc.MoveBy} 1162 * @example 1163 * // example 1164 * var actionBy = cc.MoveTo.create(2, cc.p(80, 80)); 1165 */ 1166 cc.MoveTo.create = function (duration, position, y) { 1167 return new cc.MoveTo(duration, position, y); 1168 }; 1169 1170 /** 1171 * Skews a cc.Node object to given angles by modifying it's skewX and skewY attributes 1172 * @class 1173 * @extends cc.ActionInterval 1174 */ 1175 cc.SkewTo = cc.ActionInterval.extend(/** @lends cc.SkewTo# */{ 1176 _skewX:0, 1177 _skewY:0, 1178 _startSkewX:0, 1179 _startSkewY:0, 1180 _endSkewX:0, 1181 _endSkewY:0, 1182 _deltaX:0, 1183 _deltaY:0, 1184 1185 /** 1186 * @constructor 1187 * @param {Number} t time in seconds 1188 * @param {Number} sx 1189 * @param {Number} sy 1190 * @example 1191 * var actionTo = new cc.SkewTo(2, 37.2, -37.2); 1192 */ 1193 ctor: function (t, sx, sy) { 1194 cc.ActionInterval.prototype.ctor.call(this); 1195 1196 sy !== undefined && this.initWithDuration(t, sx, sy); 1197 }, 1198 1199 /** 1200 * @param {Number} t time in seconds 1201 * @param {Number} sx 1202 * @param {Number} sy 1203 * @return {Boolean} 1204 */ 1205 initWithDuration:function (t, sx, sy) { 1206 var ret = false; 1207 if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) { 1208 this._endSkewX = sx; 1209 this._endSkewY = sy; 1210 ret = true; 1211 } 1212 return ret; 1213 }, 1214 1215 /** 1216 * returns a new clone of the action 1217 * @returns {cc.SkewTo} 1218 */ 1219 clone:function () { 1220 var action = new cc.SkewTo(); 1221 action.initWithDuration(this._duration, this._endSkewX, this._endSkewY); 1222 return action; 1223 }, 1224 1225 /** 1226 * @param {cc.Node} target 1227 */ 1228 startWithTarget:function (target) { 1229 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1230 1231 this._startSkewX = target.skewX % 180; 1232 this._deltaX = this._endSkewX - this._startSkewX; 1233 if (this._deltaX > 180) 1234 this._deltaX -= 360; 1235 if (this._deltaX < -180) 1236 this._deltaX += 360; 1237 1238 this._startSkewY = target.skewY % 360; 1239 this._deltaY = this._endSkewY - this._startSkewY; 1240 if (this._deltaY > 180) 1241 this._deltaY -= 360; 1242 if (this._deltaY < -180) 1243 this._deltaY += 360; 1244 }, 1245 1246 /** 1247 * @param {Number} t time in seconds 1248 */ 1249 update:function (t) { 1250 this.target.skewX = this._startSkewX + this._deltaX * t; 1251 this.target.skewY = this._startSkewY + this._deltaY * t; 1252 } 1253 }); 1254 /** 1255 * @param {Number} t time in seconds 1256 * @param {Number} sx 1257 * @param {Number} sy 1258 * @return {cc.SkewTo} 1259 * @example 1260 * // example 1261 * var actionTo = cc.SkewTo.create(2, 37.2, -37.2); 1262 */ 1263 cc.SkewTo.create = function (t, sx, sy) { 1264 return new cc.SkewTo(t, sx, sy); 1265 }; 1266 1267 /** Skews a cc.Node object by skewX and skewY degrees 1268 * @class 1269 * @extends cc.SkewTo 1270 */ 1271 cc.SkewBy = cc.SkewTo.extend(/** @lends cc.SkewBy# */{ 1272 1273 /** 1274 * @constructor 1275 * @param {Number} t time in seconds 1276 * @param {Number} sx skew in degrees for X axis 1277 * @param {Number} sy skew in degrees for Y axis 1278 */ 1279 ctor: function(t, sx, sy) { 1280 cc.SkewTo.prototype.ctor.call(this); 1281 sy !== undefined && this.initWithDuration(t, sx, sy); 1282 }, 1283 1284 /** 1285 * @param {Number} t time in seconds 1286 * @param {Number} deltaSkewX skew in degrees for X axis 1287 * @param {Number} deltaSkewY skew in degrees for Y axis 1288 * @return {Boolean} 1289 */ 1290 initWithDuration:function (t, deltaSkewX, deltaSkewY) { 1291 var ret = false; 1292 if (cc.SkewTo.prototype.initWithDuration.call(this, t, deltaSkewX, deltaSkewY)) { 1293 this._skewX = deltaSkewX; 1294 this._skewY = deltaSkewY; 1295 ret = true; 1296 } 1297 return ret; 1298 }, 1299 1300 /** 1301 * returns a new clone of the action 1302 * @returns {cc.SkewBy} 1303 */ 1304 clone:function () { 1305 var action = new cc.SkewBy(); 1306 action.initWithDuration(this._duration, this._skewX, this._skewY); 1307 return action; 1308 }, 1309 1310 /** 1311 * @param {cc.Node} target 1312 */ 1313 startWithTarget:function (target) { 1314 cc.SkewTo.prototype.startWithTarget.call(this, target); 1315 this._deltaX = this._skewX; 1316 this._deltaY = this._skewY; 1317 this._endSkewX = this._startSkewX + this._deltaX; 1318 this._endSkewY = this._startSkewY + this._deltaY; 1319 }, 1320 1321 /** 1322 * @return {cc.ActionInterval} 1323 */ 1324 reverse:function () { 1325 return cc.SkewBy.create(this._duration, -this._skewX, -this._skewY); 1326 } 1327 }); 1328 /** 1329 * @param {Number} t time in seconds 1330 * @param {Number} sx sx skew in degrees for X axis 1331 * @param {Number} sy sy skew in degrees for Y axis 1332 * @return {cc.SkewBy} 1333 * @example 1334 * // example 1335 * var actionBy = cc.SkewBy.create(2, 0, -90); 1336 */ 1337 cc.SkewBy.create = function (t, sx, sy) { 1338 var skewBy = new cc.SkewBy(); 1339 if (skewBy) 1340 skewBy.initWithDuration(t, sx, sy); 1341 return skewBy; 1342 }; 1343 1344 1345 /** Moves a cc.Node object simulating a parabolic jump movement by modifying it's position attribute. 1346 * @class 1347 * @extends cc.ActionInterval 1348 */ 1349 cc.JumpBy = cc.ActionInterval.extend(/** @lends cc.JumpBy# */{ 1350 _startPosition:null, 1351 _delta:null, 1352 _height:0, 1353 _jumps:0, 1354 _previousPosition:null, 1355 1356 /** 1357 * @constructor 1358 * @param {Number} duration 1359 * @param {cc.Point|Number} position 1360 * @param {Number} [y] 1361 * @param {Number} height 1362 * @param {Number} jumps 1363 * @example 1364 * var actionBy = new cc.JumpBy(2, cc.p(300, 0), 50, 4); 1365 * var actionBy = new cc.JumpBy(2, 300, 0, 50, 4); 1366 */ 1367 ctor:function (duration, position, y, height, jumps) { 1368 cc.ActionInterval.prototype.ctor.call(this); 1369 this._startPosition = cc.p(0, 0); 1370 this._previousPosition = cc.p(0, 0); 1371 this._delta = cc.p(0, 0); 1372 1373 height !== undefined && this.initWithDuration(duration, position, y, height, jumps); 1374 }, 1375 /** 1376 * @param {Number} duration 1377 * @param {cc.Point|Number} position 1378 * @param {Number} [y] 1379 * @param {Number} height 1380 * @param {Number} jumps 1381 * @return {Boolean} 1382 * @example 1383 * actionBy.initWithDuration(2, cc.p(300, 0), 50, 4); 1384 * actionBy.initWithDuration(2, 300, 0, 50, 4); 1385 */ 1386 initWithDuration:function (duration, position, y, height, jumps) { 1387 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 1388 if (jumps === undefined) { 1389 jumps = height; 1390 height = y; 1391 y = position.y; 1392 position = position.x; 1393 } 1394 this._delta.x = position; 1395 this._delta.y = y; 1396 this._height = height; 1397 this._jumps = jumps; 1398 return true; 1399 } 1400 return false; 1401 }, 1402 1403 /** 1404 * returns a new clone of the action 1405 * @returns {cc.JumpBy} 1406 */ 1407 clone:function () { 1408 var action = new cc.JumpBy(); 1409 action.initWithDuration(this._duration, this._delta, this._height, this._jumps); 1410 return action; 1411 }, 1412 1413 /** 1414 * @param {cc.Node} target 1415 */ 1416 startWithTarget:function (target) { 1417 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1418 var locPosX = target.getPositionX(); 1419 var locPosY = target.getPositionY(); 1420 this._previousPosition.x = locPosX; 1421 this._previousPosition.y = locPosY; 1422 this._startPosition.x = locPosX; 1423 this._startPosition.y = locPosY; 1424 }, 1425 1426 /** 1427 * @param {Number} time 1428 */ 1429 update:function (time) { 1430 if (this.target) { 1431 var frac = time * this._jumps % 1.0; 1432 var y = this._height * 4 * frac * (1 - frac); 1433 y += this._delta.y * time; 1434 1435 var x = this._delta.x * time; 1436 var locStartPosition = this._startPosition; 1437 if (cc.ENABLE_STACKABLE_ACTIONS) { 1438 var targetX = this.target.getPositionX(); 1439 var targetY = this.target.getPositionY(); 1440 var locPreviousPosition = this._previousPosition; 1441 1442 locStartPosition.x = locStartPosition.x + targetX - locPreviousPosition.x; 1443 locStartPosition.y = locStartPosition.y + targetY - locPreviousPosition.y; 1444 x = x + locStartPosition.x; 1445 y = y + locStartPosition.y; 1446 locPreviousPosition.x = x; 1447 locPreviousPosition.y = y; 1448 this.target.setPosition(x, y); 1449 } else { 1450 this.target.setPosition(locStartPosition.x + x, locStartPosition.y + y); 1451 } 1452 } 1453 }, 1454 1455 /** 1456 * @return {cc.ActionInterval} 1457 */ 1458 reverse:function () { 1459 return cc.JumpBy.create(this._duration, cc.p(-this._delta.x, -this._delta.y), this._height, this._jumps); 1460 } 1461 }); 1462 1463 /** 1464 * @param {Number} duration 1465 * @param {cc.Point|Number} position 1466 * @param {Number} [y] 1467 * @param {Number} height 1468 * @param {Number} jumps 1469 * @return {cc.JumpBy} 1470 * @example 1471 * // example 1472 * var actionBy = cc.JumpBy.create(2, cc.p(300, 0), 50, 4); 1473 * var actionBy = cc.JumpBy.create(2, 300, 0, 50, 4); 1474 */ 1475 cc.JumpBy.create = function (duration, position, y, height, jumps) { 1476 return new cc.JumpBy(duration, position, y, height, jumps); 1477 }; 1478 1479 /** Moves a cc.Node object to a parabolic position simulating a jump movement by modifying it's position attribute. 1480 * @class 1481 * @extends cc.JumpBy 1482 */ 1483 cc.JumpTo = cc.JumpBy.extend(/** @lends cc.JumpTo# */{ 1484 1485 /** 1486 * @param {cc.Node} target 1487 */ 1488 startWithTarget:function (target) { 1489 cc.JumpBy.prototype.startWithTarget.call(this, target); 1490 this._delta.x = this._delta.x - this._startPosition.x; 1491 this._delta.y = this._delta.y - this._startPosition.y; 1492 }, 1493 1494 /** 1495 * returns a new clone of the action 1496 * @returns {cc.JumpTo} 1497 */ 1498 clone:function () { 1499 var action = new cc.JumpTo(); 1500 action.initWithDuration(this._duration, this._delta, this._height, this._jumps); 1501 return action; 1502 } 1503 }); 1504 1505 /** 1506 * @param {Number} duration 1507 * @param {cc.Point|Number} position 1508 * @param {Number} [y] 1509 * @param {Number} height 1510 * @param {Number} jumps 1511 * @return {cc.JumpTo} 1512 * @example 1513 * // example 1514 * var actionTo = cc.JumpTo.create(2, cc.p(300, 300), 50, 4); 1515 * var actionTo = cc.JumpTo.create(2, 300, 300, 50, 4); 1516 */ 1517 cc.JumpTo.create = function (duration, position, y, height, jumps) { 1518 return new cc.JumpTo(duration, position, y, height, jumps); 1519 }; 1520 1521 /** 1522 * @function 1523 * @param {Number} a 1524 * @param {Number} b 1525 * @param {Number} c 1526 * @param {Number} d 1527 * @param {Number} t 1528 * @return {Number} 1529 */ 1530 cc.bezierAt = function (a, b, c, d, t) { 1531 return (Math.pow(1 - t, 3) * a + 1532 3 * t * (Math.pow(1 - t, 2)) * b + 1533 3 * Math.pow(t, 2) * (1 - t) * c + 1534 Math.pow(t, 3) * d ); 1535 }; 1536 1537 /** An action that moves the target with a cubic Bezier curve by a certain distance. 1538 * @class 1539 * @extends cc.ActionInterval 1540 */ 1541 cc.BezierBy = cc.ActionInterval.extend(/** @lends cc.BezierBy# */{ 1542 _config:null, 1543 _startPosition:null, 1544 _previousPosition:null, 1545 1546 /** 1547 * @constructor 1548 * @param {Number} t time in seconds 1549 * @param {Array} c Array of points 1550 * @example 1551 * var bezier = [cc.p(0, windowSize.height / 2), cc.p(300, -windowSize.height / 2), cc.p(300, 100)]; 1552 * var bezierForward = new cc.BezierBy(3, bezier); 1553 */ 1554 ctor:function (t, c) { 1555 cc.ActionInterval.prototype.ctor.call(this); 1556 this._config = []; 1557 this._startPosition = cc.p(0, 0); 1558 this._previousPosition = cc.p(0, 0); 1559 1560 c && this.initWithDuration(t, c); 1561 }, 1562 /** 1563 * @param {Number} t time in seconds 1564 * @param {Array} c Array of points 1565 * @return {Boolean} 1566 */ 1567 initWithDuration:function (t, c) { 1568 if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) { 1569 this._config = c; 1570 return true; 1571 } 1572 return false; 1573 }, 1574 1575 /** 1576 * returns a new clone of the action 1577 * @returns {cc.BezierBy} 1578 */ 1579 clone:function () { 1580 var action = new cc.BezierBy(); 1581 var newConfigs = []; 1582 for (var i = 0; i < this._config.length; i++) { 1583 var selConf = this._config[i]; 1584 newConfigs.push(cc.p(selConf.x, selConf.y)); 1585 } 1586 action.initWithDuration(this._duration, newConfigs); 1587 return action; 1588 }, 1589 1590 /** 1591 * @param {cc.Node} target 1592 */ 1593 startWithTarget:function (target) { 1594 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1595 var locPosX = target.getPositionX(); 1596 var locPosY = target.getPositionY(); 1597 this._previousPosition.x = locPosX; 1598 this._previousPosition.y = locPosY; 1599 this._startPosition.x = locPosX; 1600 this._startPosition.y = locPosY; 1601 }, 1602 1603 /** 1604 * @param {Number} time 1605 */ 1606 update:function (time) { 1607 if (this.target) { 1608 var locConfig = this._config; 1609 var xa = 0; 1610 var xb = locConfig[0].x; 1611 var xc = locConfig[1].x; 1612 var xd = locConfig[2].x; 1613 1614 var ya = 0; 1615 var yb = locConfig[0].y; 1616 var yc = locConfig[1].y; 1617 var yd = locConfig[2].y; 1618 1619 var x = cc.bezierAt(xa, xb, xc, xd, time); 1620 var y = cc.bezierAt(ya, yb, yc, yd, time); 1621 1622 var locStartPosition = this._startPosition; 1623 if (cc.ENABLE_STACKABLE_ACTIONS) { 1624 var targetX = this.target.getPositionX(); 1625 var targetY = this.target.getPositionY(); 1626 var locPreviousPosition = this._previousPosition; 1627 1628 locStartPosition.x = locStartPosition.x + targetX - locPreviousPosition.x; 1629 locStartPosition.y = locStartPosition.y + targetY - locPreviousPosition.y; 1630 x = x + locStartPosition.x; 1631 y = y + locStartPosition.y; 1632 locPreviousPosition.x = x; 1633 locPreviousPosition.y = y; 1634 this.target.setPosition(x, y); 1635 } else { 1636 this.target.setPosition(locStartPosition.x + x, locStartPosition.y + y); 1637 } 1638 } 1639 }, 1640 1641 /** 1642 * @return {cc.ActionInterval} 1643 */ 1644 reverse:function () { 1645 var locConfig = this._config; 1646 var r = [ 1647 cc.pAdd(locConfig[1], cc.pNeg(locConfig[2])), 1648 cc.pAdd(locConfig[0], cc.pNeg(locConfig[2])), 1649 cc.pNeg(locConfig[2]) ]; 1650 return cc.BezierBy.create(this._duration, r); 1651 } 1652 }); 1653 1654 /** 1655 * @param {Number} t time in seconds 1656 * @param {Array} c Array of points 1657 * @return {cc.BezierBy} 1658 * @example 1659 * // example 1660 * var bezier = [cc.p(0, windowSize.height / 2), cc.p(300, -windowSize.height / 2), cc.p(300, 100)]; 1661 * var bezierForward = cc.BezierBy.create(3, bezier); 1662 */ 1663 cc.BezierBy.create = function (t, c) { 1664 return new cc.BezierBy(t, c); 1665 }; 1666 1667 1668 /** An action that moves the target with a cubic Bezier curve to a destination point. 1669 * @class 1670 * @extends cc.BezierBy 1671 */ 1672 cc.BezierTo = cc.BezierBy.extend(/** @lends cc.BezierTo# */{ 1673 _toConfig:null, 1674 1675 /** 1676 * @constructor 1677 * @param {Number} t 1678 * @param {Array} c array of points 1679 * @example 1680 * var bezier = [cc.p(0, windowSize.height / 2), cc.p(300, -windowSize.height / 2), cc.p(300, 100)]; 1681 * var bezierTo = new cc.BezierTo(2, bezier); 1682 */ 1683 ctor:function (t, c) { 1684 cc.BezierBy.prototype.ctor.call(this); 1685 this._toConfig = []; 1686 c && this.initWithDuration(t, c); 1687 }, 1688 1689 /** 1690 * @param {Number} t time in seconds 1691 * @param {Array} c Array of points 1692 * @return {Boolean} 1693 */ 1694 initWithDuration:function (t, c) { 1695 if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) { 1696 this._toConfig = c; 1697 return true; 1698 } 1699 return false; 1700 }, 1701 1702 /** 1703 * returns a new clone of the action 1704 * @returns {cc.BezierTo} 1705 */ 1706 clone:function () { 1707 var action = new cc.BezierTo(); 1708 action.initWithDuration(this._duration, this._toConfig); 1709 return action; 1710 }, 1711 1712 /** 1713 * @param {cc.Node} target 1714 */ 1715 startWithTarget:function (target) { 1716 cc.BezierBy.prototype.startWithTarget.call(this, target); 1717 var locStartPos = this._startPosition; 1718 var locToConfig = this._toConfig; 1719 var locConfig = this._config; 1720 1721 locConfig[0] = cc.pSub(locToConfig[0], locStartPos); 1722 locConfig[1] = cc.pSub(locToConfig[1], locStartPos); 1723 locConfig[2] = cc.pSub(locToConfig[2], locStartPos); 1724 } 1725 }); 1726 /** 1727 * @param {Number} t 1728 * @param {Array} c array of points 1729 * @return {cc.BezierTo} 1730 * @example 1731 * // example 1732 * var bezier = [cc.p(0, windowSize.height / 2), cc.p(300, -windowSize.height / 2), cc.p(300, 100)]; 1733 * var bezierTo = cc.BezierTo.create(2, bezier); 1734 */ 1735 cc.BezierTo.create = function (t, c) { 1736 return new cc.BezierTo(t, c); 1737 }; 1738 1739 1740 /** Scales a cc.Node object to a zoom factor by modifying it's scale attribute. 1741 * @warning This action doesn't support "reverse" 1742 * @class 1743 * @extends cc.ActionInterval 1744 */ 1745 cc.ScaleTo = cc.ActionInterval.extend(/** @lends cc.ScaleTo# */{ 1746 _scaleX:1, 1747 _scaleY:1, 1748 _startScaleX:1, 1749 _startScaleY:1, 1750 _endScaleX:0, 1751 _endScaleY:0, 1752 _deltaX:0, 1753 _deltaY:0, 1754 1755 /** 1756 * @constructor 1757 * @param {Number} duration 1758 * @param {Number} sx scale parameter in X 1759 * @param {Number} [sy] scale parameter in Y, if Null equal to sx 1760 * @example 1761 * // It scales to 0.5 in both X and Y. 1762 * var actionTo = new cc.ScaleTo(2, 0.5); 1763 * 1764 * // It scales to 0.5 in x and 2 in Y 1765 * var actionTo = new cc.ScaleTo(2, 0.5, 2); 1766 */ 1767 ctor:function (duration, sx, sy) { 1768 cc.ActionInterval.prototype.ctor.call(this); 1769 sx !== undefined && this.initWithDuration(duration, sx, sy); 1770 }, 1771 1772 /** 1773 * @param {Number} duration 1774 * @param {Number} sx 1775 * @param {Number} [sy=] 1776 * @return {Boolean} 1777 */ 1778 initWithDuration:function (duration, sx, sy) { //function overload here 1779 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 1780 this._endScaleX = sx; 1781 this._endScaleY = (sy != null) ? sy : sx; 1782 return true; 1783 } 1784 return false; 1785 }, 1786 1787 /** 1788 * returns a new clone of the action 1789 * @returns {cc.ScaleTo} 1790 */ 1791 clone:function () { 1792 var action = new cc.ScaleTo(); 1793 action.initWithDuration(this._duration, this._endScaleX, this._endScaleY); 1794 return action; 1795 }, 1796 1797 /** 1798 * @param {cc.Node} target 1799 */ 1800 startWithTarget:function (target) { 1801 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1802 this._startScaleX = target.scaleX; 1803 this._startScaleY = target.scaleY; 1804 this._deltaX = this._endScaleX - this._startScaleX; 1805 this._deltaY = this._endScaleY - this._startScaleY; 1806 }, 1807 1808 /** 1809 * @param {Number} time 1810 */ 1811 update:function (time) { 1812 if (this.target) { 1813 this.target.scaleX = this._startScaleX + this._deltaX * time; 1814 this.target.scaleY = this._startScaleY + this._deltaY * time; 1815 } 1816 } 1817 }); 1818 /** 1819 * @param {Number} duration 1820 * @param {Number} sx scale parameter in X 1821 * @param {Number} [sy] scale parameter in Y, if Null equal to sx 1822 * @return {cc.ScaleTo} 1823 * @example 1824 * // example 1825 * // It scales to 0.5 in both X and Y. 1826 * var actionTo = cc.ScaleTo.create(2, 0.5); 1827 * 1828 * // It scales to 0.5 in x and 2 in Y 1829 * var actionTo = cc.ScaleTo.create(2, 0.5, 2); 1830 */ 1831 cc.ScaleTo.create = function (duration, sx, sy) { //function overload 1832 var scaleTo = new cc.ScaleTo(); 1833 scaleTo.initWithDuration(duration, sx, sy); 1834 return scaleTo; 1835 }; 1836 1837 1838 /** Scales a cc.Node object a zoom factor by modifying it's scale attribute. 1839 * @class 1840 * @extends cc.ScaleTo 1841 */ 1842 cc.ScaleBy = cc.ScaleTo.extend(/** @lends cc.ScaleBy# */{ 1843 /** 1844 * @param {Number} target 1845 */ 1846 startWithTarget:function (target) { 1847 cc.ScaleTo.prototype.startWithTarget.call(this, target); 1848 this._deltaX = this._startScaleX * this._endScaleX - this._startScaleX; 1849 this._deltaY = this._startScaleY * this._endScaleY - this._startScaleY; 1850 }, 1851 1852 /** 1853 * @return {cc.ActionInterval} 1854 */ 1855 reverse:function () { 1856 return cc.ScaleBy.create(this._duration, 1 / this._endScaleX, 1 / this._endScaleY); 1857 }, 1858 1859 /** 1860 * returns a new clone of the action 1861 * @returns {cc.ScaleBy} 1862 */ 1863 clone:function () { 1864 var action = new cc.ScaleBy(); 1865 action.initWithDuration(this._duration, this._endScaleX, this._endScaleY); 1866 return action; 1867 } 1868 }); 1869 /** 1870 * @param {Number} duration duration in seconds 1871 * @param {Number} sx sx scale parameter in X 1872 * @param {Number|Null} [sy=] sy scale parameter in Y, if Null equal to sx 1873 * @return {cc.ScaleBy} 1874 * @example 1875 * // example without sy, it scales by 2 both in X and Y 1876 * var actionBy = cc.ScaleBy.create(2, 2); 1877 * 1878 * //example with sy, it scales by 0.25 in X and 4.5 in Y 1879 * var actionBy2 = cc.ScaleBy.create(2, 0.25, 4.5); 1880 */ 1881 cc.ScaleBy.create = function (duration, sx, sy) { 1882 return new cc.ScaleBy(duration, sx, sy); 1883 }; 1884 1885 /** Blinks a cc.Node object by modifying it's visible attribute 1886 * @class 1887 * @extends cc.ActionInterval 1888 */ 1889 cc.Blink = cc.ActionInterval.extend(/** @lends cc.Blink# */{ 1890 _times:0, 1891 _originalState:false, 1892 1893 /** 1894 * @constructor 1895 * @param {Number} duration duration in seconds 1896 * @param (Number) blinks blinks in times 1897 * @example 1898 * var action = new cc.Blink(2, 10); 1899 */ 1900 ctor:function (duration, blinks) { 1901 cc.ActionInterval.prototype.ctor.call(this); 1902 blinks !== undefined && this.initWithDuration(duration, blinks); 1903 }, 1904 1905 /** 1906 * @param {Number} duration duration in seconds 1907 * @param {Number} blinks blinks in times 1908 * @return {Boolean} 1909 */ 1910 initWithDuration:function (duration, blinks) { 1911 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 1912 this._times = blinks; 1913 return true; 1914 } 1915 return false; 1916 }, 1917 1918 /** 1919 * returns a new clone of the action 1920 * @returns {cc.Blink} 1921 */ 1922 clone:function () { 1923 var action = new cc.Blink(); 1924 action.initWithDuration(this._duration, this._times); 1925 return action; 1926 }, 1927 1928 /** 1929 * @param {Number} time time in seconds 1930 */ 1931 update:function (time) { 1932 if (this.target && !this.isDone()) { 1933 var slice = 1.0 / this._times; 1934 var m = time % slice; 1935 this.target.visible = (m > (slice / 2)); 1936 } 1937 }, 1938 1939 startWithTarget:function (target) { 1940 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1941 this._originalState = target.visible; 1942 }, 1943 1944 stop:function () { 1945 this.target.visible = this._originalState; 1946 cc.ActionInterval.prototype.stop.call(this); 1947 }, 1948 1949 /** 1950 * @return {cc.ActionInterval} 1951 */ 1952 reverse:function () { 1953 return cc.Blink.create(this._duration, this._times); 1954 } 1955 }); 1956 /** 1957 * @param {Number} duration duration in seconds 1958 * @param blinks blinks in times 1959 * @return {cc.Blink} 1960 * @example 1961 * // example 1962 * var action = cc.Blink.create(2, 10); 1963 */ 1964 cc.Blink.create = function (duration, blinks) { 1965 var blink = new cc.Blink(); 1966 blink.initWithDuration(duration, blinks); 1967 return blink; 1968 }; 1969 1970 /** Fades an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from the current value to a custom one. 1971 * @warning This action doesn't support "reverse" 1972 * @class 1973 * @extends cc.ActionInterval 1974 */ 1975 cc.FadeTo = cc.ActionInterval.extend(/** @lends cc.FadeTo# */{ 1976 _toOpacity:0, 1977 _fromOpacity:0, 1978 1979 /** 1980 * @constructor 1981 * @param {Number} duration 1982 * @param {Number} opacity 0-255, 0 is transparent 1983 * @example 1984 * var action = new cc.FadeTo(1.0, 0); 1985 */ 1986 ctor:function (duration, opacity) { 1987 cc.ActionInterval.prototype.ctor.call(this); 1988 opacity !== undefined && this.initWithDuration(duration, opacity); 1989 }, 1990 1991 /** 1992 * @param {Number} duration duration in seconds 1993 * @param {Number} opacity 1994 * @return {Boolean} 1995 */ 1996 initWithDuration:function (duration, opacity) { 1997 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 1998 this._toOpacity = opacity; 1999 return true; 2000 } 2001 return false; 2002 }, 2003 2004 /** 2005 * returns a new clone of the action 2006 * @returns {cc.FadeTo} 2007 */ 2008 clone:function () { 2009 var action = new cc.FadeTo(); 2010 action.initWithDuration(this._duration, this._toOpacity); 2011 return action; 2012 }, 2013 2014 /** 2015 * @param {Number} time time in seconds 2016 */ 2017 update:function (time) { 2018 if (this.target.RGBAProtocol) { 2019 var fromOpacity = this._fromOpacity; 2020 this.target.opacity = fromOpacity + (this._toOpacity - fromOpacity) * time; 2021 } 2022 }, 2023 2024 /** 2025 * @param {cc.Sprite} target 2026 */ 2027 startWithTarget:function (target) { 2028 cc.ActionInterval.prototype.startWithTarget.call(this, target); 2029 if(this.target.RGBAProtocol){ 2030 this._fromOpacity = target.opacity; 2031 } 2032 } 2033 }); 2034 2035 /** 2036 * @param {Number} duration 2037 * @param {Number} opacity 0-255, 0 is transparent 2038 * @return {cc.FadeTo} 2039 * @example 2040 * // example 2041 * var action = cc.FadeTo.create(1.0, 0); 2042 */ 2043 cc.FadeTo.create = function (duration, opacity) { 2044 return new cc.FadeTo(duration, opacity); 2045 }; 2046 2047 /** Fades In an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from 0 to 255.<br/> 2048 * The "reverse" of this action is FadeOut 2049 * @class 2050 * @extends cc.FadeTo 2051 */ 2052 cc.FadeIn = cc.FadeTo.extend(/** @lends cc.FadeIn# */{ 2053 _reverseAction: null, 2054 /** 2055 * @return {cc.ActionInterval} 2056 */ 2057 reverse:function () { 2058 var action = new cc.FadeOut(); 2059 action.initWithDuration(this._duration, 0); 2060 return action; 2061 }, 2062 2063 /** 2064 * returns a new clone of the action 2065 * @returns {cc.FadeIn} 2066 */ 2067 clone:function () { 2068 var action = new cc.FadeIn(); 2069 action.initWithDuration(this._duration, this._toOpacity); 2070 return action; 2071 }, 2072 2073 /** 2074 * @param {cc.Sprite} target 2075 */ 2076 startWithTarget:function (target) { 2077 if(this._reverseAction) 2078 this._toOpacity = this._reverseAction._fromOpacity; 2079 cc.FadeTo.prototype.startWithTarget.call(this, target); 2080 } 2081 }); 2082 2083 /** 2084 * @param {Number} duration duration in seconds 2085 * @param {Number} [toOpacity] to opacity 2086 * @return {cc.FadeIn} 2087 * @example 2088 * //example 2089 * var action = cc.FadeIn.create(1.0); 2090 */ 2091 cc.FadeIn.create = function (duration, toOpacity) { 2092 if(toOpacity == null) 2093 toOpacity = 255; 2094 return new cc.FadeIn(duration, toOpacity); 2095 }; 2096 2097 2098 /** Fades Out an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from 255 to 0. 2099 * The "reverse" of this action is FadeIn 2100 * @class 2101 * @extends cc.FadeTo 2102 */ 2103 cc.FadeOut = cc.FadeTo.extend(/** @lends cc.FadeOut# */{ 2104 /** 2105 * @return {cc.ActionInterval} 2106 */ 2107 reverse:function () { 2108 var action = new cc.FadeIn(); 2109 action._reverseAction = this; 2110 action.initWithDuration(this._duration, 255); 2111 return action; 2112 }, 2113 2114 /** 2115 * returns a new clone of the action 2116 * @returns {cc.FadeOut} 2117 */ 2118 clone:function () { 2119 var action = new cc.FadeOut(); 2120 action.initWithDuration(this._duration, this._toOpacity); 2121 return action; 2122 } 2123 }); 2124 2125 /** 2126 * @param {Number} d duration in seconds 2127 * @return {cc.FadeOut} 2128 * @example 2129 * // example 2130 * var action = cc.FadeOut.create(1.0); 2131 */ 2132 cc.FadeOut.create = function (d) { 2133 var action = new cc.FadeOut(); 2134 action.initWithDuration(d, 0); 2135 return action; 2136 }; 2137 2138 /** Tints a cc.Node that implements the cc.NodeRGB protocol from current tint to a custom one. 2139 * @warning This action doesn't support "reverse" 2140 * @class 2141 * @extends cc.ActionInterval 2142 */ 2143 cc.TintTo = cc.ActionInterval.extend(/** @lends cc.TintTo# */{ 2144 _to:null, 2145 _from:null, 2146 2147 /** 2148 * @constructor 2149 * @param {Number} duration 2150 * @param {Number} red 0-255 2151 * @param {Number} green 0-255 2152 * @param {Number} blue 0-255 2153 * @example 2154 * var action = new cc.TintTo(2, 255, 0, 255); 2155 */ 2156 ctor:function (duration, red, green, blue) { 2157 cc.ActionInterval.prototype.ctor.call(this); 2158 this._to = cc.color(0, 0, 0); 2159 this._from = cc.color(0, 0, 0); 2160 2161 blue !== undefined && this.initWithDuration(duration, red, green, blue); 2162 }, 2163 2164 /** 2165 * @param {Number} duration 2166 * @param {Number} red 0-255 2167 * @param {Number} green 0-255 2168 * @param {Number} blue 0-255 2169 * @return {Boolean} 2170 */ 2171 initWithDuration:function (duration, red, green, blue) { 2172 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 2173 this._to = cc.color(red, green, blue); 2174 return true; 2175 } 2176 return false; 2177 }, 2178 2179 /** 2180 * returns a new clone of the action 2181 * @returns {cc.TintTo} 2182 */ 2183 clone:function () { 2184 var action = new cc.TintTo(); 2185 var locTo = this._to; 2186 action.initWithDuration(this._duration, locTo.r, locTo.g, locTo.b); 2187 return action; 2188 }, 2189 2190 /** 2191 * @param {cc.Sprite} target 2192 */ 2193 startWithTarget:function (target) { 2194 cc.ActionInterval.prototype.startWithTarget.call(this, target); 2195 if (this.target.RGBAProtocol) { 2196 this._from = this.target.color; 2197 } 2198 }, 2199 2200 /** 2201 * @param {Number} time time in seconds 2202 */ 2203 update:function (time) { 2204 var locFrom = this._from, locTo = this._to; 2205 if (this.target.RGBAProtocol) { 2206 this.target.color = cc.color(locFrom.r + (locTo.r - locFrom.r) * time, 2207 locFrom.g + (locTo.g - locFrom.g) * time, 2208 locFrom.b + (locTo.b - locFrom.b) * time); 2209 } 2210 } 2211 }); 2212 2213 /** 2214 * @param {Number} duration 2215 * @param {Number} red 0-255 2216 * @param {Number} green 0-255 2217 * @param {Number} blue 0-255 2218 * @return {cc.TintTo} 2219 * @example 2220 * // example 2221 * var action = cc.TintTo.create(2, 255, 0, 255); 2222 */ 2223 cc.TintTo.create = function (duration, red, green, blue) { 2224 return new cc.TintTo(duration, red, green, blue); 2225 }; 2226 2227 2228 /** Tints a cc.Node that implements the cc.NodeRGB protocol from current tint to a custom one. 2229 * @class 2230 * @extends cc.ActionInterval 2231 */ 2232 cc.TintBy = cc.ActionInterval.extend(/** @lends cc.TintBy# */{ 2233 _deltaR:0, 2234 _deltaG:0, 2235 _deltaB:0, 2236 2237 _fromR:0, 2238 _fromG:0, 2239 _fromB:0, 2240 2241 /** 2242 * @constructor 2243 * @param {Number} duration duration in seconds 2244 * @param {Number} deltaRed 2245 * @param {Number} deltaGreen 2246 * @param {Number} deltaBlue 2247 * @example 2248 * var action = new cc.TintBy(2, -127, -255, -127); 2249 */ 2250 ctor:function (duration, deltaRed, deltaGreen, deltaBlue) { 2251 cc.ActionInterval.prototype.ctor.call(this); 2252 deltaBlue !== undefined && this.initWithDuration(duration, deltaRed, deltaGreen, deltaBlue); 2253 }, 2254 2255 /** 2256 * @param {Number} duration 2257 * @param {Number} deltaRed 0-255 2258 * @param {Number} deltaGreen 0-255 2259 * @param {Number} deltaBlue 0-255 2260 * @return {Boolean} 2261 */ 2262 initWithDuration:function (duration, deltaRed, deltaGreen, deltaBlue) { 2263 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 2264 this._deltaR = deltaRed; 2265 this._deltaG = deltaGreen; 2266 this._deltaB = deltaBlue; 2267 return true; 2268 } 2269 return false; 2270 }, 2271 2272 /** 2273 * returns a new clone of the action 2274 * @returns {cc.TintBy} 2275 */ 2276 clone:function () { 2277 var action = new cc.TintBy(); 2278 action.initWithDuration(this._duration, this._deltaR, this._deltaG, this._deltaB); 2279 return action; 2280 }, 2281 2282 /** 2283 * @param {cc.Sprite} target 2284 */ 2285 startWithTarget:function (target) { 2286 cc.ActionInterval.prototype.startWithTarget.call(this, target); 2287 if (target.RGBAProtocol) { 2288 var color = target.color; 2289 this._fromR = color.r; 2290 this._fromG = color.g; 2291 this._fromB = color.b; 2292 } 2293 }, 2294 2295 /** 2296 * @param {Number} time time in seconds 2297 */ 2298 update:function (time) { 2299 if (this.target.RGBAProtocol) { 2300 this.target.color = cc.color(this._fromR + this._deltaR * time, 2301 this._fromG + this._deltaG * time, 2302 this._fromB + this._deltaB * time); 2303 } 2304 }, 2305 2306 /** 2307 * @return {cc.ActionInterval} 2308 */ 2309 reverse:function () { 2310 return cc.TintBy.create(this._duration, -this._deltaR, -this._deltaG, -this._deltaB); 2311 } 2312 }); 2313 2314 /** 2315 * @param {Number} duration duration in seconds 2316 * @param {Number} deltaRed 2317 * @param {Number} deltaGreen 2318 * @param {Number} deltaBlue 2319 * @return {cc.TintBy} 2320 * @example 2321 * // example 2322 * var action = cc.TintBy.create(2, -127, -255, -127); 2323 */ 2324 cc.TintBy.create = function (duration, deltaRed, deltaGreen, deltaBlue) { 2325 return new cc.TintBy(duration, deltaRed, deltaGreen, deltaBlue); 2326 }; 2327 2328 /** Delays the action a certain amount of seconds 2329 * @class 2330 * @extends cc.ActionInterval 2331 */ 2332 cc.DelayTime = cc.ActionInterval.extend(/** @lends cc.DelayTime# */{ 2333 /** 2334 * @param {Number} time time in seconds 2335 */ 2336 update:function (time) { 2337 }, 2338 2339 /** 2340 * @return {cc.ActionInterval} 2341 */ 2342 reverse:function () { 2343 return cc.DelayTime.create(this._duration); 2344 }, 2345 2346 /** 2347 * returns a new clone of the action 2348 * @returns {cc.DelayTime} 2349 */ 2350 clone:function () { 2351 var action = new cc.DelayTime(); 2352 action.initWithDuration(this._duration); 2353 return action; 2354 } 2355 }); 2356 2357 /** 2358 * @param {Number} d duration in seconds 2359 * @return {cc.DelayTime} 2360 * @example 2361 * // example 2362 * var delay = cc.DelayTime.create(1); 2363 */ 2364 cc.DelayTime.create = function (d) { 2365 return new cc.DelayTime(d); 2366 }; 2367 2368 /** 2369 * Executes an action in reverse order, from time=duration to time=0 2370 * @warning Use this action carefully. This action is not 2371 * sequenceable. Use it as the default "reversed" method 2372 * of your own actions, but using it outside the "reversed" 2373 * scope is not recommended. 2374 * @class 2375 * @extends cc.ActionInterval 2376 */ 2377 cc.ReverseTime = cc.ActionInterval.extend(/** @lends cc.ReverseTime# */{ 2378 _other:null, 2379 2380 /** 2381 * @constructor 2382 * @param {cc.FiniteTimeAction} action 2383 * @example 2384 * var reverse = new cc.ReverseTime(this); 2385 */ 2386 ctor:function (action) { 2387 cc.ActionInterval.prototype.ctor.call(this); 2388 this._other = null; 2389 2390 action && this.initWithAction(action); 2391 }, 2392 2393 /** 2394 * @param {cc.FiniteTimeAction} action 2395 * @return {Boolean} 2396 */ 2397 initWithAction:function (action) { 2398 if(!action) 2399 throw "cc.ReverseTime.initWithAction(): action must be non null"; 2400 if(action == this._other) 2401 throw "cc.ReverseTime.initWithAction(): the action was already passed in."; 2402 2403 if (cc.ActionInterval.prototype.initWithDuration.call(this, action.getDuration())) { 2404 // Don't leak if action is reused 2405 this._other = action; 2406 return true; 2407 } 2408 return false; 2409 }, 2410 2411 /** 2412 * returns a new clone of the action 2413 * @returns {cc.ReverseTime} 2414 */ 2415 clone:function () { 2416 var action = new cc.ReverseTime(); 2417 action.initWithAction(this._other.clone()); 2418 return action; 2419 }, 2420 2421 /** 2422 * @param {cc.Node} target 2423 */ 2424 startWithTarget:function (target) { 2425 cc.ActionInterval.prototype.startWithTarget.call(this, target); 2426 this._other.startWithTarget(target); 2427 }, 2428 2429 /** 2430 * @param {Number} time time in seconds 2431 */ 2432 update:function (time) { 2433 if (this._other) 2434 this._other.update(1 - time); 2435 }, 2436 2437 /** 2438 * @return {cc.ActionInterval} 2439 */ 2440 reverse:function () { 2441 return this._other.clone(); 2442 }, 2443 2444 /** 2445 * Stop the action 2446 */ 2447 stop:function () { 2448 this._other.stop(); 2449 cc.Action.prototype.stop.call(this); 2450 } 2451 }); 2452 2453 /** 2454 * @param {cc.FiniteTimeAction} action 2455 * @return {cc.ReverseTime} 2456 * @example 2457 * // example 2458 * var reverse = cc.ReverseTime.create(this); 2459 */ 2460 cc.ReverseTime.create = function (action) { 2461 return new cc.ReverseTime(action); 2462 }; 2463 2464 2465 /** Animates a sprite given the name of an Animation 2466 * @class 2467 * @extends cc.ActionInterval 2468 */ 2469 cc.Animate = cc.ActionInterval.extend(/** @lends cc.Animate# */{ 2470 _animation:null, 2471 _nextFrame:0, 2472 _origFrame:null, 2473 _executedLoops:0, 2474 _splitTimes:null, 2475 2476 /** 2477 * @constructor 2478 * create the animate with animation 2479 * @param {cc.Animation} animation 2480 * @example 2481 * // create the animation with animation 2482 * var anim = new cc.Animate(dance_grey); 2483 */ 2484 ctor:function (animation) { 2485 cc.ActionInterval.prototype.ctor.call(this); 2486 this._splitTimes = []; 2487 2488 animation && this.initWithAnimation(animation); 2489 }, 2490 2491 /** 2492 * @return {cc.Animation} 2493 */ 2494 getAnimation:function () { 2495 return this._animation; 2496 }, 2497 2498 /** 2499 * @param {cc.Animation} animation 2500 */ 2501 setAnimation:function (animation) { 2502 this._animation = animation; 2503 }, 2504 2505 /** 2506 * @param {cc.Animation} animation 2507 * @return {Boolean} 2508 */ 2509 initWithAnimation:function (animation) { 2510 if(!animation) 2511 throw "cc.Animate.initWithAnimation(): animation must be non-NULL"; 2512 var singleDuration = animation.getDuration(); 2513 if (this.initWithDuration(singleDuration * animation.getLoops())) { 2514 this._nextFrame = 0; 2515 this.setAnimation(animation); 2516 2517 this._origFrame = null; 2518 this._executedLoops = 0; 2519 var locTimes = this._splitTimes; 2520 locTimes.length = 0; 2521 2522 var accumUnitsOfTime = 0; 2523 var newUnitOfTimeValue = singleDuration / animation.getTotalDelayUnits(); 2524 2525 var frames = animation.getFrames(); 2526 cc.arrayVerifyType(frames, cc.AnimationFrame); 2527 2528 for (var i = 0; i < frames.length; i++) { 2529 var frame = frames[i]; 2530 var value = (accumUnitsOfTime * newUnitOfTimeValue) / singleDuration; 2531 accumUnitsOfTime += frame.getDelayUnits(); 2532 locTimes.push(value); 2533 } 2534 return true; 2535 } 2536 return false; 2537 }, 2538 2539 /** 2540 * returns a new clone of the action 2541 * @returns {cc.Animate} 2542 */ 2543 clone:function () { 2544 var action = new cc.Animate(); 2545 action.initWithAnimation(this._animation.clone()); 2546 return action; 2547 }, 2548 2549 /** 2550 * @param {cc.Sprite} target 2551 */ 2552 startWithTarget:function (target) { 2553 cc.ActionInterval.prototype.startWithTarget.call(this, target); 2554 if (this._animation.getRestoreOriginalFrame()) 2555 this._origFrame = target.displayFrame(); 2556 this._nextFrame = 0; 2557 this._executedLoops = 0; 2558 }, 2559 2560 /** 2561 * @param {Number} time 2562 */ 2563 update:function (time) { 2564 // if t==1, ignore. Animation should finish with t==1 2565 if (time < 1.0) { 2566 time *= this._animation.getLoops(); 2567 2568 // new loop? If so, reset frame counter 2569 var loopNumber = 0 | time; 2570 if (loopNumber > this._executedLoops) { 2571 this._nextFrame = 0; 2572 this._executedLoops++; 2573 } 2574 2575 // new t for animations 2576 time = time % 1.0; 2577 } 2578 2579 var frames = this._animation.getFrames(); 2580 var numberOfFrames = frames.length, locSplitTimes = this._splitTimes; 2581 for (var i = this._nextFrame; i < numberOfFrames; i++) { 2582 if (locSplitTimes[i] <= time) { 2583 this.target.setSpriteFrame(frames[i].getSpriteFrame()); 2584 this._nextFrame = i + 1; 2585 } else { 2586 // Issue 1438. Could be more than one frame per tick, due to low frame rate or frame delta < 1/FPS 2587 break; 2588 } 2589 } 2590 }, 2591 2592 /** 2593 * @return {cc.ActionInterval} 2594 */ 2595 reverse:function () { 2596 var locAnimation = this._animation; 2597 var oldArray = locAnimation.getFrames(); 2598 var newArray = []; 2599 cc.arrayVerifyType(oldArray, cc.AnimationFrame); 2600 if (oldArray.length > 0) { 2601 for (var i = oldArray.length - 1; i >= 0; i--) { 2602 var element = oldArray[i]; 2603 if (!element) 2604 break; 2605 newArray.push(element.clone()); 2606 } 2607 } 2608 var newAnim = cc.Animation.create(newArray, locAnimation.getDelayPerUnit(), locAnimation.getLoops()); 2609 newAnim.setRestoreOriginalFrame(locAnimation.getRestoreOriginalFrame()); 2610 return cc.Animate.create(newAnim); 2611 }, 2612 2613 /** 2614 * stop the action 2615 */ 2616 stop:function () { 2617 if (this._animation.getRestoreOriginalFrame() && this.target) 2618 this.target.setSpriteFrame(this._origFrame); 2619 cc.Action.prototype.stop.call(this); 2620 } 2621 }); 2622 2623 /** 2624 * create the animate with animation 2625 * @param {cc.Animation} animation 2626 * @return {cc.Animate} 2627 * @example 2628 * // example 2629 * // create the animation with animation 2630 * var anim = cc.Animate.create(dance_grey); 2631 */ 2632 cc.Animate.create = function (animation) { 2633 return new cc.Animate(animation); 2634 }; 2635 2636 /** 2637 * <p> 2638 * Overrides the target of an action so that it always runs on the target<br/> 2639 * specified at action creation rather than the one specified by runAction. 2640 * </p> 2641 * @class 2642 * @extends cc.ActionInterval 2643 */ 2644 cc.TargetedAction = cc.ActionInterval.extend(/** @lends cc.TargetedAction# */{ 2645 _action:null, 2646 _forcedTarget:null, 2647 2648 /** 2649 * Create an action with the specified action and forced target 2650 * @constructor 2651 * @param {cc.Node} target 2652 * @param {cc.FiniteTimeAction} action 2653 */ 2654 ctor: function (target, action) { 2655 cc.ActionInterval.prototype.ctor.call(this); 2656 action && this.initWithTarget(target, action); 2657 }, 2658 2659 /** 2660 * Init an action with the specified action and forced target 2661 * @param {cc.Node} target 2662 * @param {cc.FiniteTimeAction} action 2663 * @return {Boolean} 2664 */ 2665 initWithTarget:function (target, action) { 2666 if (this.initWithDuration(action.getDuration())) { 2667 this._forcedTarget = target; 2668 this._action = action; 2669 return true; 2670 } 2671 return false; 2672 }, 2673 2674 /** 2675 * returns a new clone of the action 2676 * @returns {cc.TargetedAction} 2677 */ 2678 clone:function () { 2679 var action = new cc.TargetedAction(); 2680 action.initWithTarget(this._forcedTarget, this._action.clone()); 2681 return action; 2682 }, 2683 2684 startWithTarget:function (target) { 2685 cc.ActionInterval.prototype.startWithTarget.call(this, target); 2686 this._action.startWithTarget(this._forcedTarget); 2687 }, 2688 2689 stop:function () { 2690 this._action.stop(); 2691 }, 2692 2693 update:function (time) { 2694 this._action.update(time); 2695 }, 2696 2697 /** 2698 * return the target that the action will be forced to run with 2699 * @return {cc.Node} 2700 */ 2701 getForcedTarget:function () { 2702 return this._forcedTarget; 2703 }, 2704 2705 /** 2706 * set the target that the action will be forced to run with 2707 * @param {cc.Node} forcedTarget 2708 */ 2709 setForcedTarget:function (forcedTarget) { 2710 if (this._forcedTarget != forcedTarget) 2711 this._forcedTarget = forcedTarget; 2712 } 2713 }); 2714 2715 /** 2716 * Create an action with the specified action and forced target 2717 * @param {cc.Node} target 2718 * @param {cc.FiniteTimeAction} action 2719 * @return {cc.TargetedAction} 2720 */ 2721 cc.TargetedAction.create = function (target, action) { 2722 return new cc.TargetedAction(target, action); 2723 }; 2724