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 /** how many seconds had elapsed since the actions started to run. 51 * @return {Number} 52 */ 53 getElapsed:function () { 54 return this._elapsed; 55 }, 56 57 /** initializes the action 58 * @param {Number} d duration in seconds 59 * @return {Boolean} 60 */ 61 initWithDuration:function (d) { 62 this._duration = (d == 0) ? cc.FLT_EPSILON : d; 63 // prevent division by 0 64 // This comparison could be in step:, but it might decrease the performance 65 // by 3% in heavy based action games. 66 this._elapsed = 0; 67 this._firstTick = true; 68 return true; 69 }, 70 71 /** returns true if the action has finished 72 * @return {Boolean} 73 */ 74 isDone:function () { 75 return (this._elapsed >= this._duration); 76 }, 77 78 /** 79 * @param {Number} dt delta time in seconds 80 */ 81 step:function (dt) { 82 if (this._firstTick) { 83 this._firstTick = false; 84 this._elapsed = 0; 85 } else { 86 this._elapsed += dt; 87 } 88 //this.update((1 > (this._elapsed / this._duration)) ? this._elapsed / this._duration : 1); 89 //this.update(Math.max(0, Math.min(1, this._elapsed / Math.max(this._duration, cc.FLT_EPSILON)))); 90 var t = this._elapsed / (this._duration > 0.0000001192092896 ? this._duration : 0.0000001192092896); 91 t = (1 > t ? t : 1); 92 this.update(t > 0 ? t : 0); 93 }, 94 95 /** 96 * @param {cc.Node} target 97 */ 98 startWithTarget:function (target) { 99 //this._super(target); 100 cc.Action.prototype.startWithTarget.call(this, target); 101 this._elapsed = 0; 102 this._firstTick = true; 103 }, 104 105 /** 106 * @return {Null} 107 */ 108 reverse:function () { 109 cc.Assert(false, "cc.IntervalAction: reverse not implemented."); 110 return null; 111 }, 112 113 /** 114 * @param {Number} amp 115 */ 116 setAmplitudeRate:function (amp) { 117 // Abstract class needs implementation 118 cc.Assert(0, 'Actioninterval setAmplitudeRate'); 119 }, 120 121 /** 122 * @return {Number} 123 */ 124 getAmplitudeRate:function () { 125 // Abstract class needs implementation 126 cc.Assert(0, 'Actioninterval getAmplitudeRate'); 127 return 0; 128 } 129 }); 130 131 /** 132 * @param {Number} d duration in seconds 133 * @return {cc.ActionInterval} 134 * @example 135 * // example 136 * var actionInterval = cc.ActionInterval.create(3); 137 */ 138 cc.ActionInterval.create = function (d) { 139 var action = new cc.ActionInterval(); 140 action.initWithDuration(d); 141 return action; 142 }; 143 144 145 /** Runs actions sequentially, one after another 146 * @class 147 * @extends cc.ActionInterval 148 */ 149 cc.Sequence = cc.ActionInterval.extend(/** @lends cc.Sequence# */{ 150 _actions:null, 151 _split:null, 152 _last:0, 153 154 /** 155 * Constructor 156 */ 157 ctor:function () { 158 this._actions = []; 159 }, 160 161 /** initializes the action <br/> 162 * @param {cc.FiniteTimeAction} actionOne 163 * @param {cc.FiniteTimeAction} actionTwo 164 * @return {Boolean} 165 */ 166 initOneTwo:function (actionOne, actionTwo) { 167 cc.Assert(actionOne != null, "Sequence.initOneTwo"); 168 cc.Assert(actionTwo != null, "Sequence.initOneTwo"); 169 170 var one = actionOne.getDuration(); 171 var two = actionTwo.getDuration(); 172 173 var d = actionOne.getDuration() + actionTwo.getDuration(); 174 this.initWithDuration(d); 175 176 this._actions[0] = actionOne; 177 this._actions[1] = actionTwo; 178 179 return true; 180 }, 181 182 /** 183 * @param {cc.Node} target 184 */ 185 startWithTarget:function (target) { 186 cc.ActionInterval.prototype.startWithTarget.call(this, target); 187 //this._super(target); 188 this._split = this._actions[0].getDuration() / this._duration; 189 this._last = -1; 190 }, 191 192 /** 193 * stop the action 194 */ 195 stop:function () { 196 // Issue #1305 197 if (this._last != -1) { 198 this._actions[this._last].stop(); 199 } 200 cc.Action.prototype.stop.call(this); 201 }, 202 203 /** 204 * @param {Number} time time in seconds 205 */ 206 update:function (time) { 207 var new_t, found = 0; 208 if (time < this._split) { 209 // action[0] 210 new_t = (this._split) ? time / this._split : 1; 211 } else { 212 // action[1] 213 found = 1; 214 new_t = (this._split == 1) ? 1 : (time - this._split) / (1 - this._split); 215 216 if (this._last == -1) { 217 // action[0] was skipped, execute it. 218 this._actions[0].startWithTarget(this._target); 219 this._actions[0].update(1); 220 this._actions[0].stop(); 221 } 222 if (!this._last) { 223 // switching to action 1. stop action 0. 224 this._actions[0].update(1); 225 this._actions[0].stop(); 226 } 227 } 228 229 // Last action found and it is done. 230 if(this._last == found && this._actions[found].isDone()) 231 return; 232 233 // Last action found and it is done 234 if (this._last != found) 235 this._actions[found].startWithTarget(this._target); 236 237 this._actions[found].update(new_t); 238 this._last = found; 239 }, 240 241 /** 242 * @return {cc.ActionInterval} 243 */ 244 reverse:function () { 245 return cc.Sequence._actionOneTwo(this._actions[1].reverse(), this._actions[0].reverse()); 246 }, 247 248 /** 249 * to copy object with deep copy. 250 * @return {object} 251 */ 252 copy:function () { 253 return cc.Sequence._actionOneTwo(this._actions[0].copy(), this._actions[1].copy() ); 254 } 255 }); 256 /** helper constructor to create an array of sequenceable actions 257 * @param {Array|cc.FiniteTimeAction} tempArray 258 * @return {cc.FiniteTimeAction} 259 * @example 260 * // example 261 * // create sequence with actions 262 * var seq = cc.Sequence.create(act1, act2); 263 * 264 * // create sequence with array 265 * var seq = cc.Sequence.create(actArray); 266 */ 267 cc.Sequence.create = function (/*Multiple Arguments*/tempArray) { 268 var paraArray = (tempArray instanceof Array) ? tempArray : arguments; 269 var prev = paraArray[0]; 270 for (var i = 1; i < paraArray.length; i++) { 271 if (paraArray[i]) { 272 prev = cc.Sequence._actionOneTwo(prev, paraArray[i]); 273 } 274 } 275 return prev; 276 }; 277 278 /** creates the action 279 * @param {cc.FiniteTimeAction} actionOne 280 * @param {cc.FiniteTimeAction} actionTwo 281 * @return {cc.Sequence} 282 * @private 283 */ 284 cc.Sequence._actionOneTwo = function (actionOne, actionTwo) { 285 var sequence = new cc.Sequence(); 286 sequence.initOneTwo(actionOne, actionTwo); 287 return sequence; 288 }; 289 290 291 /** Repeats an action a number of times. 292 * To repeat an action forever use the CCRepeatForever action. 293 * @class 294 * @extends cc.ActionInterval 295 */ 296 cc.Repeat = cc.ActionInterval.extend(/** @lends cc.Repeat# */{ 297 _times:0, 298 _total:0, 299 _nextDt:0, 300 _actionInstant:false, 301 _innerAction:null, //CCFiniteTimeAction 302 303 /** 304 * @param {cc.FiniteTimeAction} action 305 * @param {Number} times 306 * @return {Boolean} 307 */ 308 initWithAction:function (action, times) { 309 var duration = action.getDuration() * times; 310 311 if (this.initWithDuration(duration)) { 312 this._times = times; 313 this._innerAction = action; 314 315 if (action instanceof cc.ActionInstant) { 316 this._times -= 1; 317 } 318 319 this._total = 0; 320 return true; 321 } 322 return false; 323 }, 324 325 /** 326 * @param {cc.Node} target 327 */ 328 startWithTarget:function (target) { 329 this._total = 0; 330 this._nextDt = this._innerAction.getDuration() / this._duration; 331 //this._super(target); 332 cc.ActionInterval.prototype.startWithTarget.call(this, target); 333 this._innerAction.startWithTarget(target); 334 }, 335 336 /** 337 * stop the action 338 */ 339 stop:function () { 340 this._innerAction.stop(); 341 cc.Action.prototype.stop.call(this); 342 }, 343 344 /** 345 * @param {Number} time time in seconds 346 */ 347 update:function (time) { 348 if (time >= this._nextDt) { 349 while (time > this._nextDt && this._total < this._times) { 350 this._innerAction.update(1); 351 this._total++; 352 this._innerAction.stop(); 353 this._innerAction.startWithTarget(this._target); 354 this._nextDt += this._innerAction.getDuration() / this._duration; 355 } 356 357 // fix for issue #1288, incorrect end value of repeat 358 if (time >= 1.0 && this._total < this._times) { 359 this._total++; 360 } 361 362 // don't set a instantaction back or update it, it has no use because it has no duration 363 if (this._actionInstant) { 364 if (this._total == this._times) { 365 this._innerAction.update(1); 366 this._innerAction.stop(); 367 } else { 368 // issue #390 prevent jerk, use right update 369 this._innerAction.update(time - (this._nextDt - this._innerAction.getDuration() / this._duration)); 370 } 371 } 372 } else { 373 this._innerAction.update((time * this._times) % 1.0); 374 } 375 }, 376 377 /** 378 * @return {Boolean} 379 */ 380 isDone:function () { 381 return this._total == this._times; 382 }, 383 384 /** 385 * @return {cc.ActionInterval} 386 */ 387 reverse:function () { 388 return cc.Repeat.create(this._innerAction.reverse(), this._times); 389 }, 390 391 /** 392 * @param {cc.FiniteTimeAction} action 393 */ 394 setInnerAction:function (action) { 395 if (this._innerAction != action) { 396 this._innerAction = action; 397 } 398 }, 399 400 /** 401 * @return {cc.FiniteTimeAction} 402 */ 403 getInnerAction:function () { 404 return this._innerAction; 405 } 406 }); 407 /** creates a CCRepeat action. Times is an unsigned integer between 1 and pow(2,30) 408 * @param {cc.FiniteTimeAction} action 409 * @param {Number} times 410 * @return {cc.Repeat} 411 * @example 412 * // example 413 * var rep = cc.Repeat.create(cc.Sequence.create(jump2, jump1), 5); 414 */ 415 cc.Repeat.create = function (action, times) { 416 var repeat = new cc.Repeat(); 417 repeat.initWithAction(action, times); 418 return repeat; 419 }; 420 421 422 /** Repeats an action for ever. <br/> 423 * To repeat the an action for a limited number of times use the Repeat action. <br/> 424 * @warning This action can't be Sequenceable because it is not an IntervalAction 425 * @class 426 * @extends cc.ActionInterval 427 */ 428 429 cc.RepeatForever = cc.ActionInterval.extend(/** @lends cc.RepeatForever# */{ 430 _innerAction:null, //CCActionInterval 431 432 /** 433 * @param {cc.ActionInterval} action 434 * @return {Boolean} 435 */ 436 initWithAction:function (action) { 437 cc.Assert(action != null, ""); 438 439 this._innerAction = action; 440 return true; 441 }, 442 443 /** 444 * @param {cc.Node} target 445 */ 446 startWithTarget:function (target) { 447 //this._super(target); 448 cc.ActionInterval.prototype.startWithTarget.call(this, target); 449 this._innerAction.startWithTarget(target); 450 }, 451 452 /** 453 * @param dt delta time in seconds 454 */ 455 step:function (dt) { 456 this._innerAction.step(dt); 457 if (this._innerAction.isDone()) { 458 //var diff = this._innerAction.getElapsed() - this._innerAction.getDuration(); 459 this._innerAction.startWithTarget(this._target); 460 // to prevent jerk. issue #390 ,1247 461 //this._innerAction.step(0); 462 //this._innerAction.step(diff); 463 this._innerAction.step(this._innerAction.getElapsed() - this._innerAction.getDuration()); 464 } 465 }, 466 467 /** 468 * @return {Boolean} 469 */ 470 isDone:function () { 471 return false; 472 }, 473 474 /** 475 * @return {cc.ActionInterval} 476 */ 477 reverse:function () { 478 return (cc.RepeatForever.create(this._innerAction.reverse())); 479 }, 480 481 /** 482 * 483 * @param {cc.ActionInterval} action 484 */ 485 setInnerAction:function (action) { 486 if (this._innerAction != action) { 487 this._innerAction = action; 488 } 489 }, 490 491 /** 492 * @return {cc.ActionInterval} 493 */ 494 getInnerAction:function () { 495 return this._innerAction; 496 } 497 }); 498 /** 499 * Repeat the acton forever 500 * @param action 501 * @return {cc.RepeatForever} 502 * @example 503 * // example 504 * var repeat = cc.RepeatForever.create(cc.RotateBy.create(1.0, 360)); 505 */ 506 cc.RepeatForever.create = function (action) { 507 var ret = new cc.RepeatForever(); 508 if (ret && ret.initWithAction(action)) { 509 return ret; 510 } 511 return null; 512 }; 513 514 515 /** Spawn a new action immediately 516 * @class 517 * @extends cc.ActionInterval 518 */ 519 cc.Spawn = cc.ActionInterval.extend(/** @lends cc.Spawn# */{ 520 /** initializes the Spawn action with the 2 actions to spawn 521 * @param {cc.FiniteTimeAction} action1 522 * @param {cc.FiniteTimeAction} action2 523 * @return {Boolean} 524 */ 525 initOneTwo:function (action1, action2) { 526 cc.Assert(action1 != null, "no action1"); 527 cc.Assert(action2 != null, "no action2"); 528 529 var ret = false; 530 531 var d1 = action1.getDuration(); 532 var d2 = action2.getDuration(); 533 534 if (this.initWithDuration(Math.max(d1, d2))) { 535 this._one = action1; 536 this._two = action2; 537 538 if (d1 > d2) { 539 this._two = cc.Sequence._actionOneTwo(action2, cc.DelayTime.create(d1 - d2)); 540 } else if (d1 < d2) { 541 this._one = cc.Sequence._actionOneTwo(action1, cc.DelayTime.create(d2 - d1)); 542 } 543 544 ret = true; 545 } 546 return ret; 547 }, 548 549 /** 550 * @param {cc.Node} target 551 */ 552 startWithTarget:function (target) { 553 cc.ActionInterval.prototype.startWithTarget.call(this, target); 554 this._one.startWithTarget(target); 555 this._two.startWithTarget(target); 556 }, 557 558 /** 559 * Stop the action 560 */ 561 stop:function () { 562 this._one.stop(); 563 this._two.stop(); 564 cc.Action.prototype.stop.call(this); 565 }, 566 567 /** 568 * @param {Number} time time in seconds 569 */ 570 update:function (time) { 571 if (this._one) { 572 this._one.update(time); 573 } 574 if (this._two) { 575 this._two.update(time); 576 } 577 }, 578 579 /** 580 * @return {cc.FiniteTimeAction} 581 */ 582 reverse:function () { 583 return cc.Spawn._actionOneTwo(this._one.reverse(), this._two.reverse()); 584 }, 585 _one:null, 586 _two:null 587 }); 588 589 /** 590 * @param {Array|cc.FiniteTimeAction}tempArray 591 * @return {cc.FiniteTimeAction} 592 * @example 593 * // example 594 * var action = cc.Spawn.create(cc.JumpBy.create(2, cc.p(300, 0), 50, 4), cc.RotateBy.create(2, 720)); 595 */ 596 cc.Spawn.create = function (/*Multiple Arguments*/tempArray) { 597 var paramArray = (tempArray instanceof Array) ? tempArray : arguments; 598 var prev = paramArray[0]; 599 for (var i = 1; i < paramArray.length; i++) { 600 if (paramArray[i] != null) { 601 prev = this._actionOneTwo(prev, paramArray[i]); 602 } 603 } 604 return prev; 605 }; 606 607 /** 608 * @param {cc.FiniteTimeAction} action1 609 * @param {cc.FiniteTimeAction} action2 610 * @return {cc.Spawn} 611 * @private 612 */ 613 cc.Spawn._actionOneTwo = function (action1, action2) { 614 var pSpawn = new cc.Spawn(); 615 pSpawn.initOneTwo(action1, action2); 616 617 return pSpawn; 618 }; 619 620 621 /** Rotates a cc.Node object to a certain angle by modifying it's 622 * rotation attribute. <br/> 623 * The direction will be decided by the shortest angle. 624 * @class 625 * @extends cc.ActionInterval 626 */ 627 cc.RotateTo = cc.ActionInterval.extend(/** @lends cc.RotateTo# */{ 628 _dstAngle:0, 629 _startAngle:0, 630 _diffAngle:0, 631 /** 632 * @param {Number} duration 633 * @param {Number} deltaAngle 634 * @return {Boolean} 635 */ 636 initWithDuration:function (duration, deltaAngle) { 637 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 638 this._dstAngle = deltaAngle || 0; 639 return true; 640 } 641 return false; 642 }, 643 644 /** 645 * @param {cc.Node} target 646 */ 647 startWithTarget:function (target) { 648 cc.ActionInterval.prototype.startWithTarget.call(this, target); 649 650 this._startAngle = target.getRotation(); 651 if (this._startAngle > 0) 652 this._startAngle = this._startAngle % 360.0; 653 else 654 this._startAngle = this._startAngle % 360.0; 655 656 this._diffAngle = this._dstAngle - this._startAngle; 657 if (this._diffAngle > 180) 658 this._diffAngle -= 360; 659 660 if (this._diffAngle < -180) 661 this._diffAngle += 360; 662 }, 663 664 /** 665 * RotateTo reverse not implemented 666 */ 667 reverse:function () { 668 cc.Assert(0, "RotateTo reverse not implemented"); 669 }, 670 671 /** 672 * @param {Number} time time in seconds 673 */ 674 update:function (time) { 675 if (this._target) 676 this._target.setRotation(this._startAngle + this._diffAngle * time); 677 } 678 }); 679 680 /** 681 * @param {Number} duration duration in seconds 682 * @param {Number} deltaAngle deltaAngle in degrees. 683 * @return {cc.RotateTo} 684 * @example 685 * // example 686 * var rotateTo = cc.RotateTo.create(2, 61.0); 687 */ 688 cc.RotateTo.create = function (duration, deltaAngle) { 689 var rotateTo = new cc.RotateTo(); 690 rotateTo.initWithDuration(duration, deltaAngle); 691 692 return rotateTo; 693 }; 694 695 696 /** Rotates a cc.Node object clockwise a number of degrees by modifying it's rotation attribute. 697 * @class 698 * @extends cc.ActionInterval 699 */ 700 cc.RotateBy = cc.ActionInterval.extend(/** @lends cc.RotateBy# */{ 701 _angle:0, 702 _startAngle:0, 703 704 /** 705 * @param {Number} duration duration in seconds 706 * @param {Number} deltaAngle deltaAngle in degrees 707 * @return {Boolean} 708 */ 709 initWithDuration:function (duration, deltaAngle) { 710 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 711 this._angle = deltaAngle; 712 return true; 713 } 714 715 return false; 716 }, 717 718 /** 719 * @param {cc.Node} target 720 */ 721 startWithTarget:function (target) { 722 cc.ActionInterval.prototype.startWithTarget.call(this, target); 723 this._startAngle = target.getRotation(); 724 }, 725 726 /** 727 * @param {Number} time 728 */ 729 update:function (time) { 730 if (this._target) { 731 this._target.setRotation(this._startAngle + this._angle * time); 732 } 733 }, 734 735 /** 736 * @return {cc.ActionInterval} 737 */ 738 reverse:function () { 739 return cc.RotateBy.create(this._duration, -this._angle); 740 } 741 }); 742 743 /** 744 * @param {Number} duration druation in seconds 745 * @param {Number} deltaAngle deltaAngle in degrees 746 * @return {cc.RotateBy} 747 * @example 748 * // example 749 * var actionBy = cc.RotateBy.create(2, 360); 750 */ 751 cc.RotateBy.create = function (duration, deltaAngle) { 752 var rotateBy = new cc.RotateBy(); 753 rotateBy.initWithDuration(duration, deltaAngle); 754 755 return rotateBy; 756 }; 757 758 759 /** Moves a cc.Node object to the position x,y. x and y are absolute coordinates by modifying it's position attribute. 760 * @class 761 * @extends cc.ActionInterval 762 */ 763 cc.MoveTo = cc.ActionInterval.extend(/** @lends cc.MoveTo# */{ 764 /** 765 * @param {Number} duration duration in seconds 766 * @param {cc.Poin} position 767 * @return {Boolean} 768 */ 769 initWithDuration:function (duration, position) { 770 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 771 this._endPosition = position; 772 return true; 773 } 774 775 return false; 776 }, 777 778 /** 779 * @param {Number} target 780 */ 781 startWithTarget:function (target) { 782 cc.ActionInterval.prototype.startWithTarget.call(this, target); 783 this._startPosition = target.getPosition(); 784 this._delta = cc.pSub(this._endPosition, this._startPosition); 785 }, 786 787 /** 788 * @param {Number} time time in seconds 789 */ 790 update:function (time) { 791 if (this._target) { 792 this._target.setPosition(cc.p(this._startPosition.x + this._delta.x * time, 793 this._startPosition.y + this._delta.y * time)); 794 } 795 }, 796 797 /** 798 * MoveTo reverse is not implemented 799 */ 800 reverse:function () { 801 cc.Assert(0, "moveto reverse is not implemented"); 802 }, 803 _endPosition:cc.p(0, 0), 804 _startPosition:cc.p(0, 0), 805 _delta:cc.p(0, 0) 806 }); 807 808 /** 809 * @param {Number} duration duration in seconds 810 * @param {cc.Point} position 811 * @return {cc.MoveTo} 812 * @example 813 * // example 814 * var actionTo = cc.MoveTo.create(2, cc.p(windowSize.width - 40, windowSize.height - 40)); 815 */ 816 cc.MoveTo.create = function (duration, position) { 817 var moveTo = new cc.MoveTo(); 818 moveTo.initWithDuration(duration, position); 819 820 return moveTo; 821 }; 822 823 824 /** Moves a cc.Node object x,y pixels by modifying it's position attribute. <br/> 825 * x and y are relative to the position of the object. <br/> 826 * @class 827 * @extends cc.MoveTo 828 */ 829 cc.MoveBy = cc.MoveTo.extend(/** @lends cc.MoveBy# */{ 830 831 /** 832 * @param {Number} duration duration in seconds 833 * @param {cc.Point} position 834 * @return {Boolean} 835 */ 836 initWithDuration:function (duration, position) { 837 if (cc.MoveTo.prototype.initWithDuration.call(this, duration, position)) { 838 this._delta = position; 839 return true; 840 } 841 842 return false; 843 }, 844 845 /** 846 * @param {cc.Node} target 847 */ 848 startWithTarget:function (target) { 849 var temp = this._delta; 850 cc.MoveTo.prototype.startWithTarget.call(this, target); 851 this._delta = temp; 852 }, 853 854 /** 855 * @return {cc.ActionInterval} 856 */ 857 reverse:function () { 858 return cc.MoveBy.create(this._duration, cc.p(-this._delta.x, -this._delta.y)); 859 } 860 }); 861 /** 862 * @param {Number} duration duration in seconds 863 * @param {cc.Point} position 864 * @return {cc.MoveBy} 865 * @example 866 * // example 867 * var actionBy = cc.MoveBy.create(2, cc.p(80, 80)); 868 */ 869 cc.MoveBy.create = function (duration, position) { 870 var moveBy = new cc.MoveBy(); 871 moveBy.initWithDuration(duration, position); 872 873 return moveBy; 874 }; 875 876 877 /** Skews a cc.Node object to given angles by modifying it's skewX and skewY attributes 878 * @class 879 * @extends cc.ActionInterval 880 */ 881 cc.SkewTo = cc.ActionInterval.extend(/** @lends cc.SkewTo# */{ 882 /** 883 * @param {Number} t time in seconds 884 * @param {Number} sx 885 * @param {Number} sy 886 * @return {Boolean} 887 */ 888 initWithDuration:function (t, sx, sy) { 889 var ret = false; 890 891 if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) { 892 this._endSkewX = sx; 893 this._endSkewY = sy; 894 895 ret = true; 896 } 897 898 return ret; 899 }, 900 901 /** 902 * @param {cc.Node} target 903 */ 904 startWithTarget:function (target) { 905 cc.ActionInterval.prototype.startWithTarget.call(this, target); 906 907 this._startSkewX = target.getSkewX(); 908 909 910 if (this._startSkewX > 0) { 911 this._startSkewX = this._startSkewX % 180; 912 } 913 else { 914 this._startSkewX = this._startSkewX % -180; 915 } 916 917 this._deltaX = this._endSkewX - this._startSkewX; 918 919 if (this._deltaX > 180) { 920 this._deltaX -= 360; 921 } 922 if (this._deltaX < -180) { 923 this._deltaX += 360; 924 } 925 926 927 this._startSkewY = target.getSkewY(); 928 if (this._startSkewY > 0) { 929 this._startSkewY = this._startSkewY % 360; 930 } 931 else { 932 this._startSkewY = this._startSkewY % -360; 933 } 934 935 this._deltaY = this._endSkewY - this._startSkewY; 936 937 if (this._deltaY > 180) { 938 this._deltaY -= 360; 939 } 940 if (this._deltaY < -180) { 941 this._deltaY += 360; 942 } 943 }, 944 945 /** 946 * @param {Number} t time in seconds 947 */ 948 update:function (t) { 949 this._target.setSkewX(this._startSkewX + this._deltaX * t); 950 951 this._target.setSkewY(this._startSkewY + this._deltaY * t); 952 }, 953 _skewX:0, 954 _skewY:0, 955 _startSkewX:0, 956 _startSkewY:0, 957 _endSkewX:0, 958 _endSkewY:0, 959 _deltaX:0, 960 _deltaY:0 961 }); 962 /** 963 * @param {Number} t time in seconds 964 * @param {Number} sx 965 * @param {Number} sy 966 * @return {cc.SkewTo} 967 * @example 968 * // example 969 * var actionTo = cc.SkewTo.create(2, 37.2, -37.2); 970 */ 971 972 cc.SkewTo.create = function (t, sx, sy) { 973 var skewTo = new cc.SkewTo(); 974 if (skewTo) { 975 skewTo.initWithDuration(t, sx, sy) 976 } 977 return skewTo; 978 }; 979 980 981 /** Skews a cc.Node object by skewX and skewY degrees 982 * @class 983 * @extends cc.SkewTo 984 */ 985 cc.SkewBy = cc.SkewTo.extend(/** @lends cc.SkewBy# */{ 986 /** 987 * @param {Number} t time in seconds 988 * @param {Number} deltaSkewX skew in degrees for X axis 989 * @param {Number} deltaSkewY skew in degrees for Y axis 990 * @return {Boolean} 991 */ 992 initWithDuration:function (t, deltaSkewX, deltaSkewY) { 993 var ret = false; 994 995 if (cc.SkewTo.prototype.initWithDuration.call(this, t, deltaSkewX, deltaSkewY)) { 996 this._skewX = deltaSkewX; 997 this._skewY = deltaSkewY; 998 999 ret = true; 1000 } 1001 1002 return ret; 1003 }, 1004 1005 /** 1006 * @param {cc.Node} target 1007 */ 1008 startWithTarget:function (target) { 1009 cc.SkewTo.prototype.startWithTarget.call(this, target); 1010 this._deltaX = this._skewX; 1011 this._deltaY = this._skewY; 1012 this._endSkewX = this._startSkewX + this._deltaX; 1013 this._endSkewY = this._startSkewY + this._deltaY; 1014 }, 1015 1016 /** 1017 * @return {cc.ActionInterval} 1018 */ 1019 reverse:function () { 1020 return cc.SkewBy.create(this._duration, -this._skewX, -this._skewY); 1021 } 1022 }); 1023 /** 1024 * @param {Number} t time in seconds 1025 * @param {Number} sx sx skew in degrees for X axis 1026 * @param {Number} sy sy skew in degrees for Y axis 1027 * @return {cc.SkewBy} 1028 * @example 1029 * // example 1030 * var actionBy = cc.SkewBy.create(2, 0, -90); 1031 */ 1032 cc.SkewBy.create = function (t, sx, sy) { 1033 var skewBy = new cc.SkewBy(); 1034 if (skewBy) { 1035 skewBy.initWithDuration(t, sx, sy); 1036 } 1037 1038 return skewBy; 1039 }; 1040 1041 1042 /** Moves a cc.Node object simulating a parabolic jump movement by modifying it's position attribute. 1043 * @class 1044 * @extends cc.ActionInterval 1045 */ 1046 cc.JumpBy = cc.ActionInterval.extend(/** @lends cc.JumpBy# */{ 1047 /** 1048 * @param {Number} duration 1049 * @param {cc.Point} position 1050 * @param {Number} height 1051 * @param {Number} jumps 1052 * @return {Boolean} 1053 */ 1054 initWithDuration:function (duration, position, height, jumps) { 1055 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 1056 this._delta = position; 1057 this._height = height; 1058 this._jumps = jumps; 1059 1060 return true; 1061 } 1062 1063 return false; 1064 }, 1065 1066 /** 1067 * @param {cc.Node} target 1068 */ 1069 startWithTarget:function (target) { 1070 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1071 this._startPosition = target.getPosition(); 1072 }, 1073 1074 /** 1075 * @param {Number} time 1076 */ 1077 update:function (time) { 1078 if (this._target) { 1079 var frac = time * this._jumps % 1.0; 1080 var y = this._height * 4 * frac * (1 - frac); 1081 y += this._delta.y * time; 1082 var x = this._delta.x * time; 1083 this._target.setPosition(cc.p(this._startPosition.x + x, this._startPosition.y + y)); 1084 } 1085 }, 1086 1087 /** 1088 * @return {cc.ActionInterval} 1089 */ 1090 reverse:function () { 1091 return cc.JumpBy.create(this._duration, cc.p(-this._delta.x, -this._delta.y), this._height, this._jumps); 1092 }, 1093 _startPosition:cc.p(0, 0), 1094 _delta:cc.p(0, 0), 1095 _height:0, 1096 _jumps:0 1097 }); 1098 1099 /** 1100 * @param {Number} duration 1101 * @param {cc.Point} position 1102 * @param {Number} height 1103 * @param {Number} jumps 1104 * @return {cc.JumpBy} 1105 * @example 1106 * // example 1107 * var actionBy = cc.JumpBy.create(2, cc.p(300, 0), 50, 4); 1108 */ 1109 cc.JumpBy.create = function (duration, position, height, jumps) { 1110 var jumpBy = new cc.JumpBy(); 1111 jumpBy.initWithDuration(duration, position, height, jumps); 1112 1113 return jumpBy; 1114 }; 1115 1116 1117 /** Moves a cc.Node object to a parabolic position simulating a jump movement by modifying it's position attribute. 1118 * @class 1119 * @extends cc.JumpBy 1120 */ 1121 cc.JumpTo = cc.JumpBy.extend(/** @lends cc.JumpTo# */{ 1122 /** 1123 * @param {cc.Node} target 1124 */ 1125 startWithTarget:function (target) { 1126 cc.JumpBy.prototype.startWithTarget.call(this, target); 1127 this._delta = cc.p(this._delta.x - this._startPosition.x, this._delta.y - this._startPosition.y); 1128 } 1129 }); 1130 1131 /** 1132 * @param {Number} duration 1133 * @param {cc.Point} position 1134 * @param {Number} height 1135 * @param {Number} jumps 1136 * @return {cc.JumpTo} 1137 * @example 1138 * // example 1139 * var actionTo = cc.JumpTo.create(2, cc.p(300, 300), 50, 4); 1140 */ 1141 cc.JumpTo.create = function (duration, position, height, jumps) { 1142 var jumpTo = new cc.JumpTo(); 1143 jumpTo.initWithDuration(duration, position, height, jumps); 1144 1145 return jumpTo; 1146 }; 1147 1148 1149 /** 1150 * @function 1151 * @param {Number} a 1152 * @param {Number} b 1153 * @param {Number} c 1154 * @param {Number} d 1155 * @param {Number} t 1156 * @return {Number} 1157 */ 1158 cc.bezierat = function (a, b, c, d, t) { 1159 return (Math.pow(1 - t, 3) * a + 1160 3 * t * (Math.pow(1 - t, 2)) * b + 1161 3 * Math.pow(t, 2) * (1 - t) * c + 1162 Math.pow(t, 3) * d ); 1163 }; 1164 1165 /** An action that moves the target with a cubic Bezier curve by a certain distance. 1166 * @class 1167 * @extends cc.ActionInterval 1168 */ 1169 cc.BezierBy = cc.ActionInterval.extend(/** @lends cc.BezierBy# */{ 1170 /** 1171 * @param {Number} t time in seconds 1172 * @param {Array} c Array of points 1173 * @return {Boolean} 1174 */ 1175 initWithDuration:function (t, c) { 1176 if (cc.ActionInterval.prototype.initWithDuration.call(this, t)) { 1177 this._config = c; 1178 return true; 1179 } 1180 return false; 1181 }, 1182 1183 /** 1184 * @param {cc.Node} target 1185 */ 1186 startWithTarget:function (target) { 1187 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1188 this._startPosition = target.getPosition(); 1189 }, 1190 1191 /** 1192 * @param {Number} time 1193 */ 1194 update:function (time) { 1195 if (this._target) { 1196 var xa = 0; 1197 var xb = this._config[0].x; 1198 var xc = this._config[1].x; 1199 var xd = this._config[2].x; 1200 1201 var ya = 0; 1202 var yb = this._config[0].y; 1203 var yc = this._config[1].y; 1204 var yd = this._config[2].y; 1205 1206 var x = cc.bezierat(xa, xb, xc, xd, time); 1207 var y = cc.bezierat(ya, yb, yc, yd, time); 1208 this._target.setPosition(cc.pAdd(this._startPosition, cc.p(x, y))); 1209 } 1210 }, 1211 1212 /** 1213 * @return {cc.ActionInterval} 1214 */ 1215 reverse:function () { 1216 var r = [ 1217 cc.pAdd(this._config[1], cc.pNeg(this._config[2]) ), 1218 cc.pAdd(this._config[0], cc.pNeg(this._config[2]) ), 1219 cc.pNeg(this._config[2]) ]; 1220 1221 return cc.BezierBy.create(this._duration, r); 1222 }, 1223 1224 /** 1225 * Constructor 1226 */ 1227 ctor:function () { 1228 this._config = []; 1229 this._startPosition = cc.p(0, 0); 1230 } 1231 }); 1232 1233 /** 1234 * @param {Number} t time in seconds 1235 * @param {Array} c Array of points 1236 * @return {cc.BezierBy} 1237 * @example 1238 * // example 1239 * var bezier = [cc.p(0, windowSize.height / 2), cc.p(300, -windowSize.height / 2), cc.p(300, 100)]; 1240 * var bezierForward = cc.BezierBy.create(3, bezier); 1241 * 1242 */ 1243 cc.BezierBy.create = function (t, c) { 1244 var bezierBy = new cc.BezierBy(); 1245 bezierBy.initWithDuration(t, c); 1246 1247 return bezierBy; 1248 }; 1249 1250 1251 /** An action that moves the target with a cubic Bezier curve to a destination point. 1252 * @class 1253 * @extends cc.BezierBy 1254 */ 1255 cc.BezierTo = cc.BezierBy.extend(/** @lends cc.BezierTo# */{ 1256 _toConfig:null, 1257 /** 1258 * @param {Number} t time in seconds 1259 * @param {Array} c Array of points 1260 * @return {Boolean} 1261 */ 1262 initWithDuration:function (t, c) { 1263 if(cc.BezierBy.prototype.initWithDuration.call(this, t, c)){ 1264 this._toConfig = []; 1265 this._toConfig[0] = cc.p(c[0].x, c[0].y); 1266 this._toConfig[1] = cc.p(c[1].x, c[1].y); 1267 this._toConfig[2] = cc.p(c[2].x, c[2].y); 1268 return true; 1269 } 1270 return false; 1271 }, 1272 /** 1273 * @param {cc.Node} target 1274 */ 1275 startWithTarget:function (target) { 1276 cc.BezierBy.prototype.startWithTarget.call(this, target); 1277 this._config[0] = cc.pSub(this._toConfig[0], this._startPosition); 1278 this._config[1] = cc.pSub(this._toConfig[1], this._startPosition); 1279 this._config[2] = cc.pSub(this._toConfig[2], this._startPosition); 1280 } 1281 }); 1282 /** 1283 * @param {Number} t 1284 * @param {Array} c array of points 1285 * @return {cc.BezierTo} 1286 * @example 1287 * // example 1288 * var bezier = [cc.p(0, windowSize.height / 2), cc.p(300, -windowSize.height / 2), cc.p(300, 100)]; 1289 * var bezierTo = cc.BezierTo.create(2, bezier); 1290 */ 1291 cc.BezierTo.create = function (t, c) { 1292 var bezierTo = new cc.BezierTo(); 1293 bezierTo.initWithDuration(t, c); 1294 1295 return bezierTo; 1296 }; 1297 1298 1299 /** Scales a cc.Node object to a zoom factor by modifying it's scale attribute. 1300 * @warning This action doesn't support "reverse" 1301 * @class 1302 * @extends cc.ActionInterval 1303 */ 1304 cc.ScaleTo = cc.ActionInterval.extend(/** @lends cc.ScaleTo# */{ 1305 /** 1306 * @param {Number} duration 1307 * @param {Number} sx 1308 * @param {Number} sy 1309 * @return {Boolean} 1310 */ 1311 initWithDuration:function (duration, sx, sy) { //function overload here 1312 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 1313 this._endScaleX = sx; 1314 this._endScaleY = (sy != null) ? sy : sx; 1315 return true; 1316 } 1317 return false; 1318 }, 1319 1320 /** 1321 * @param {cc.Node} target 1322 */ 1323 startWithTarget:function (target) { 1324 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1325 this._startScaleX = target.getScaleX(); 1326 this._startScaleY = target.getScaleY(); 1327 this._deltaX = this._endScaleX - this._startScaleX; 1328 this._deltaY = this._endScaleY - this._startScaleY; 1329 }, 1330 1331 /** 1332 * @param {Number} time 1333 */ 1334 update:function (time) { 1335 if (this._target) 1336 this._target.setScale(this._startScaleX + this._deltaX * time, this._startScaleY + this._deltaY * time); 1337 }, 1338 _scaleX:1, 1339 _scaleY:1, 1340 _startScaleX:1, 1341 _startScaleY:1, 1342 _endScaleX:0, 1343 _endScaleY:0, 1344 _deltaX:0, 1345 _deltaY:0 1346 }); 1347 /** 1348 * @param {Number} duration 1349 * @param {Number} sx scale parameter in X 1350 * @param {Number|Null} sy scale parameter in Y, if Null equal to sx 1351 * @return {cc.ScaleTo} 1352 * @example 1353 * // example 1354 * // It scales to 0.5 in both X and Y. 1355 * var actionTo = cc.ScaleTo.create(2, 0.5); 1356 * 1357 * // It scales to 0.5 in x and 2 in Y 1358 * var actionTo = cc.ScaleTo.create(2, 0.5, 2); 1359 */ 1360 cc.ScaleTo.create = function (duration, sx, sy){ //function overload 1361 var scaleTo = new cc.ScaleTo(); 1362 if (sy) 1363 scaleTo.initWithDuration(duration, sx, sy); 1364 else 1365 scaleTo.initWithDuration(duration, sx); 1366 1367 return scaleTo; 1368 }; 1369 1370 1371 /** Scales a cc.Node object a zoom factor by modifying it's scale attribute. 1372 * @class 1373 * @extends cc.ScaleTo 1374 */ 1375 cc.ScaleBy = cc.ScaleTo.extend(/** @lends cc.ScaleBy# */{ 1376 /** 1377 * @param {Number} target 1378 */ 1379 startWithTarget:function (target) { 1380 //this._super(target); 1381 cc.ScaleTo.prototype.startWithTarget.call(this, target); 1382 this._deltaX = this._startScaleX * this._endScaleX - this._startScaleX; 1383 this._deltaY = this._startScaleY * this._endScaleY - this._startScaleY; 1384 }, 1385 1386 /** 1387 * @return {cc.ActionInterval} 1388 */ 1389 reverse:function () { 1390 return cc.ScaleBy.create(this._duration, 1 / this._endScaleX, 1 / this._endScaleY); 1391 } 1392 }); 1393 /** 1394 * @param {Number} duration duration in seconds 1395 * @param {Number} sx sx scale parameter in X 1396 * @param {Number|Null} sy sy scale parameter in Y, if Null equal to sx 1397 * @return {cc.ScaleBy} 1398 * @example 1399 * // example without sy, it scales by 2 both in X and Y 1400 * var actionBy = cc.ScaleBy.create(2, 2); 1401 * 1402 * //example with sy, it scales by 0.25 in X and 4.5 in Y 1403 * var actionBy2 = cc.ScaleBy.create(2, 0.25, 4.5); 1404 */ 1405 cc.ScaleBy.create = function (duration, sx, sy) { 1406 var scaleBy = new cc.ScaleBy(); 1407 if (arguments.length == 3) { 1408 scaleBy.initWithDuration(duration, sx, sy); 1409 } else { 1410 scaleBy.initWithDuration(duration, sx); 1411 } 1412 return scaleBy; 1413 }; 1414 1415 /** Blinks a cc.Node object by modifying it's visible attribute 1416 * @class 1417 * @extends cc.ActionInterval 1418 */ 1419 cc.Blink = cc.ActionInterval.extend(/** @lends cc.Blink# */{ 1420 /** 1421 * @param {Number} duration duration in seconds 1422 * @param {Number} blinks blinks in times 1423 * @return {Boolean} 1424 */ 1425 initWithDuration:function (duration, blinks) { 1426 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 1427 this._times = blinks; 1428 return true; 1429 } 1430 return false; 1431 }, 1432 1433 /** 1434 * @param {Number} time time in seconds 1435 */ 1436 update:function (time) { 1437 if (this._target && !this.isDone()) { 1438 var slice = 1.0 / this._times; 1439 var m = time % slice; 1440 this._target.setVisible(m > slice / 2 ? true : false); 1441 } 1442 }, 1443 1444 startWithTarget:function(target){ 1445 this._super(target); 1446 this._originalState = target.isVisible(); 1447 }, 1448 1449 stop:function(){ 1450 this._target.setVisible(this._originalState); 1451 this._super(); 1452 }, 1453 1454 /** 1455 * @return {cc.ActionInterval} 1456 */ 1457 reverse:function () { 1458 return cc.Blink.create(this._duration, this._times); 1459 }, 1460 _times:0, 1461 _originalState:false 1462 }); 1463 /** 1464 * @param {Number} duration duration in seconds 1465 * @param blinks blinks in times 1466 * @return {cc.Blink} 1467 * @example 1468 * // example 1469 * var action = cc.Blink.create(2, 10); 1470 */ 1471 cc.Blink.create = function (duration, blinks) { 1472 var blink = new cc.Blink(); 1473 blink.initWithDuration(duration, blinks); 1474 return blink; 1475 }; 1476 1477 1478 /** Fades In an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from 0 to 255.<br/> 1479 * The "reverse" of this action is FadeOut 1480 * @class 1481 * @extends cc.ActionInterval 1482 */ 1483 cc.FadeIn = cc.ActionInterval.extend(/** @lends cc.FadeIn# */{ 1484 /** 1485 * @param {Number} time time in seconds 1486 */ 1487 update:function (time) { 1488 this._target.setOpacity(255 * time); 1489 }, 1490 1491 /** 1492 * @return {cc.ActionInterval} 1493 */ 1494 reverse:function () { 1495 return cc.FadeOut.create(this._duration); 1496 } 1497 }); 1498 1499 /** 1500 * @param {Number} duration duration in seconds 1501 * @return {cc.FadeIn} 1502 * @example 1503 * //example 1504 * var action = cc.FadeIn.create(1.0); 1505 */ 1506 cc.FadeIn.create = function (duration) { 1507 var action = new cc.FadeIn(); 1508 action.initWithDuration(duration); 1509 return action; 1510 }; 1511 1512 1513 /** Fades Out an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from 255 to 0. 1514 * The "reverse" of this action is FadeIn 1515 * @class 1516 * @extends cc.ActionInterval 1517 */ 1518 cc.FadeOut = cc.ActionInterval.extend(/** @lends cc.FadeOut# */{ 1519 /** 1520 * @param {Number} time time in seconds 1521 */ 1522 update:function (time) { 1523 this._target.setOpacity(255 * (1 - time)); 1524 }, 1525 1526 /** 1527 * @return {cc.ActionInterval} 1528 */ 1529 reverse:function () { 1530 return cc.FadeIn.create(this._duration); 1531 } 1532 }); 1533 1534 /** 1535 * @param {Number} d duration in seconds 1536 * @return {cc.FadeOut} 1537 * @example 1538 * // example 1539 * var action = cc.FadeOut.create(1.0); 1540 */ 1541 cc.FadeOut.create = function (d) { 1542 var action = new cc.FadeOut(); 1543 1544 action.initWithDuration(d); 1545 1546 return action; 1547 }; 1548 1549 1550 /** Fades an object that implements the cc.RGBAProtocol protocol. It modifies the opacity from the current value to a custom one. 1551 * @warning This action doesn't support "reverse" 1552 * @class 1553 * @extends cc.ActionInterval 1554 */ 1555 cc.FadeTo = cc.ActionInterval.extend(/** @lends cc.FadeTo# */{ 1556 /** 1557 * @param {Number} duration duration in seconds 1558 * @param {Number} opacity 1559 * @return {Boolean} 1560 */ 1561 initWithDuration:function (duration, opacity) { 1562 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 1563 this._toOpacity = opacity; 1564 return true; 1565 } 1566 return false; 1567 }, 1568 1569 /** 1570 * @param {Number} time time in seconds 1571 */ 1572 update:function (time) { 1573 this._target.setOpacity((this._fromOpacity + (this._toOpacity - this._fromOpacity) * time)); 1574 }, 1575 1576 /** 1577 * @param {cc.Sprite} target 1578 */ 1579 startWithTarget:function (target) { 1580 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1581 this._fromOpacity = target.getOpacity(); 1582 }, 1583 _toOpacity:'', 1584 _fromOpacity:'' 1585 }); 1586 1587 /** 1588 * @param {Number} duration 1589 * @param {Number} opacity 0-255, 0 is transparent 1590 * @return {cc.FadeTo} 1591 * @example 1592 * // example 1593 * var action = cc.FadeTo.create(1.0, 0); 1594 */ 1595 cc.FadeTo.create = function (duration, opacity) { 1596 var fadeTo = new cc.FadeTo(); 1597 fadeTo.initWithDuration(duration, opacity); 1598 1599 return fadeTo; 1600 }; 1601 1602 1603 /** Tints a cc.Node that implements the cc.NodeRGB protocol from current tint to a custom one. 1604 * @warning This action doesn't support "reverse" 1605 * @class 1606 * @extends cc.ActionInterval 1607 */ 1608 cc.TintTo = cc.ActionInterval.extend(/** @lends cc.TintTo# */{ 1609 /** 1610 * @param {Number} duration 1611 * @param {Number} red 0-255 1612 * @param {Number} green 0-255 1613 * @param {Number} blue 0-255 1614 * @return {Boolean} 1615 */ 1616 initWithDuration:function (duration, red, green, blue) { 1617 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 1618 this._to = cc.c3b(red, green, blue); 1619 return true; 1620 } 1621 1622 return false; 1623 }, 1624 1625 /** 1626 * @param {cc.Sprite} target 1627 */ 1628 startWithTarget:function (target) { 1629 //this._super(target); 1630 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1631 this._from = this._target.getColor(); 1632 }, 1633 1634 /** 1635 * @param {Number} time time in seconds 1636 */ 1637 update:function (time) { 1638 this._target.setColor(cc.c3b(this._from.r + (this._to.r - this._from.r) * time, 1639 (this._from.g + (this._to.g - this._from.g) * time), 1640 (this._from.b + (this._to.b - this._from.b) * time))); 1641 }, 1642 _to:new cc.Color3B(), 1643 _from:new cc.Color3B() 1644 }); 1645 1646 /** 1647 * @param {Number} duration 1648 * @param {Number} red 0-255 1649 * @param {Number} green 0-255 1650 * @param {Number} blue 0-255 1651 * @return {cc.TintTo} 1652 * @example 1653 * // example 1654 * var action = cc.TintTo.create(2, 255, 0, 255); 1655 */ 1656 cc.TintTo.create = function (duration, red, green, blue) { 1657 var tintTo = new cc.TintTo(); 1658 tintTo.initWithDuration(duration, red, green, blue); 1659 1660 return tintTo; 1661 }; 1662 1663 1664 /** Tints a cc.Node that implements the cc.NodeRGB protocol from current tint to a custom one. 1665 * @class 1666 * @extends cc.ActionInterval 1667 */ 1668 cc.TintBy = cc.ActionInterval.extend(/** @lends cc.TintBy# */{ 1669 /** 1670 * @param {Number} duration 1671 * @param {Number} deltaRed 0-255 1672 * @param {Number} deltaGreen 0-255 1673 * @param {Number} deltaBlue 0-255 1674 * @return {Boolean} 1675 */ 1676 initWithDuration:function (duration, deltaRed, deltaGreen, deltaBlue) { 1677 //if (this._super(duration)) { 1678 if (cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { 1679 this._deltaR = deltaRed; 1680 this._deltaG = deltaGreen; 1681 this._deltaB = deltaBlue; 1682 1683 return true; 1684 } 1685 1686 return false; 1687 }, 1688 1689 /** 1690 * @param {cc.Sprite} target 1691 */ 1692 startWithTarget:function (target) { 1693 //this._super(target); 1694 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1695 1696 if (target.RGBAProtocol) { 1697 var color = target.getColor(); 1698 this._fromR = color.r; 1699 this._fromG = color.g; 1700 this._fromB = color.b; 1701 } 1702 }, 1703 1704 /** 1705 * @param {Number} time time in seconds 1706 */ 1707 update:function (time) { 1708 if (this._target.RGBAProtocol) { 1709 this._target.setColor(cc.c3b((this._fromR + this._deltaR * time), 1710 (this._fromG + this._deltaG * time), 1711 (this._fromB + this._deltaB * time))); 1712 } 1713 }, 1714 1715 /** 1716 * @return {cc.ActionInterval} 1717 */ 1718 reverse:function () { 1719 return cc.TintBy.create(this._duration, -this._deltaR, -this._deltaG, -this._deltaB); 1720 }, 1721 _deltaR:0, 1722 _deltaG:0, 1723 _deltaB:0, 1724 1725 _fromR:0, 1726 _fromG:0, 1727 _fromB:0 1728 }); 1729 1730 /** 1731 * @param {Number} duration duration in seconds 1732 * @param {Number} deltaRed 1733 * @param {Number} deltaGreen 1734 * @param {Number} deltaBlue 1735 * @return {cc.TintBy} 1736 * @example 1737 * // example 1738 * var action = cc.TintBy.create(2, -127, -255, -127); 1739 */ 1740 cc.TintBy.create = function (duration, deltaRed, deltaGreen, deltaBlue) { 1741 var tintBy = new cc.TintBy(); 1742 tintBy.initWithDuration(duration, deltaRed, deltaGreen, deltaBlue); 1743 1744 return tintBy; 1745 }; 1746 1747 1748 /** Delays the action a certain amount of seconds 1749 * @class 1750 * @extends cc.ActionInterval 1751 */ 1752 cc.DelayTime = cc.ActionInterval.extend(/** @lends cc.DelayTime# */{ 1753 1754 /** 1755 * @param {Number} time time in seconds 1756 */ 1757 update:function (time) { 1758 1759 }, 1760 1761 /** 1762 * @return {cc.ActionInterval} 1763 */ 1764 reverse:function () { 1765 return cc.DelayTime.create(this._duration); 1766 } 1767 }); 1768 1769 /** 1770 * @param {Number} d duration in seconds 1771 * @return {cc.DelayTime} 1772 * @example 1773 * // example 1774 * var delay = cc.DelayTime.create(1); 1775 */ 1776 cc.DelayTime.create = function (d) { 1777 var action = new cc.DelayTime(); 1778 1779 action.initWithDuration(d); 1780 1781 return action; 1782 }; 1783 1784 1785 /** Executes an action in reverse order, from time=duration to time=0 1786 1787 * @warning Use this action carefully. This action is not 1788 * sequenceable. Use it as the default "reversed" method 1789 * of your own actions, but using it outside the "reversed" 1790 * scope is not recommended. 1791 * @class 1792 * @extends cc.ActionInterval 1793 */ 1794 cc.ReverseTime = cc.ActionInterval.extend(/** @lends cc.ReverseTime# */{ 1795 /** 1796 * @param {cc.FiniteTimeAction} action 1797 * @return {Boolean} 1798 */ 1799 initWithAction:function (action) { 1800 cc.Assert(action != null, ""); 1801 cc.Assert(action != this._other, ""); 1802 1803 //if (this._super(action.getDuration())) { 1804 if (cc.ActionInterval.prototype.initWithDuration.call(this, action.getDuration())) { 1805 // Don't leak if action is reused 1806 this._other = action; 1807 return true; 1808 } 1809 1810 return false; 1811 }, 1812 1813 /** 1814 * @param {cc.Node} target 1815 */ 1816 startWithTarget:function (target) { 1817 //this._super(target); 1818 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1819 this._other.startWithTarget(target); 1820 }, 1821 1822 /** 1823 * @param {Number} time time in seconds 1824 */ 1825 update:function (time) { 1826 if (this._other) { 1827 this._other.update(1 - time); 1828 } 1829 }, 1830 1831 /** 1832 * @return {cc.ActionInterval} 1833 */ 1834 reverse:function () { 1835 return this._other.copy(); 1836 }, 1837 1838 /** 1839 * Stop the action 1840 */ 1841 stop:function () { 1842 this._other.stop(); 1843 //this._super(); 1844 cc.Action.prototype.stop.call(this); 1845 }, 1846 _other:null 1847 }); 1848 1849 /** 1850 * @param {cc.FiniteTimeAction} action 1851 * @return {cc.ReverseTime} 1852 * @example 1853 * // example 1854 * var reverse = cc.ReverseTime.create(this); 1855 */ 1856 cc.ReverseTime.create = function (action) { 1857 var reverseTime = new cc.ReverseTime(); 1858 reverseTime.initWithAction(action); 1859 1860 return reverseTime; 1861 }; 1862 1863 1864 /** Animates a sprite given the name of an Animation 1865 * @class 1866 * @extends cc.ActionInterval 1867 */ 1868 cc.Animate = cc.ActionInterval.extend(/** @lends cc.Animate# */{ 1869 _animation:null, 1870 _nextFrame:0, 1871 _origFrame:null, 1872 _executedLoops:0, 1873 _splitTimes:null, 1874 1875 /** 1876 * @return {cc.Animation} 1877 */ 1878 getAnimation:function () { 1879 return this._animation; 1880 }, 1881 1882 /** 1883 * @param {cc.Animation} animation 1884 */ 1885 setAnimation:function (animation) { 1886 this._animation = animation; 1887 }, 1888 1889 /** 1890 * @param {cc.Animation} animation 1891 * @return {Boolean} 1892 */ 1893 initWithAnimation:function (animation) { 1894 cc.Assert(animation != null, "Animate: argument Animation must be non-NULL"); 1895 1896 var singleDuration = animation.getDuration(); 1897 if (this.initWithDuration(singleDuration * animation.getLoops())) { 1898 this._nextFrame = 0; 1899 this.setAnimation(animation); 1900 1901 this._origFrame = null; 1902 this._executedLoops = 0; 1903 1904 this._splitTimes = []; 1905 1906 var accumUnitsOfTime = 0; 1907 var newUnitOfTimeValue = singleDuration / animation.getTotalDelayUnits(); 1908 1909 var frames = animation.getFrames(); 1910 cc.ArrayVerifyType(frames, cc.AnimationFrame); 1911 1912 for (var i = 0; i < frames.length; i++) { 1913 var frame = frames[i]; 1914 var value = (accumUnitsOfTime * newUnitOfTimeValue) / singleDuration; 1915 accumUnitsOfTime += frame.getDelayUnits(); 1916 this._splitTimes.push(value); 1917 } 1918 return true; 1919 } 1920 return false; 1921 }, 1922 1923 /** 1924 * @param {cc.Sprite} target 1925 */ 1926 startWithTarget:function (target) { 1927 //this._super(target); 1928 cc.ActionInterval.prototype.startWithTarget.call(this, target); 1929 1930 if (this._animation.getRestoreOriginalFrame()) { 1931 this._origFrame = target.displayFrame(); 1932 } 1933 this._nextFrame = 0; 1934 this._executedLoops = 0; 1935 }, 1936 1937 /** 1938 * @param {Number} time 1939 */ 1940 update:function (time) { 1941 // if t==1, ignore. Animation should finish with t==1 1942 if (time < 1.0) { 1943 time *= this._animation.getLoops(); 1944 1945 // new loop? If so, reset frame counter 1946 var loopNumber = 0 | time; 1947 if (loopNumber > this._executedLoops) { 1948 this._nextFrame = 0; 1949 this._executedLoops++; 1950 } 1951 1952 // new t for animations 1953 time = time % 1.0; 1954 } 1955 1956 var frames = this._animation.getFrames(); 1957 var numberOfFrames = frames.length; 1958 for (var i = this._nextFrame; i < numberOfFrames; i++) { 1959 if (this._splitTimes[i] <= time) { 1960 this._target.setDisplayFrame(frames[i].getSpriteFrame()); 1961 //var dict = frame.getUserInfo(); 1962 //if (dict) { 1963 //TODO: [[NSNotificationCenter defaultCenter] postNotificationName:CCAnimationFrameDisplayedNotification object:target_ userInfo:dict]; 1964 //} 1965 this._nextFrame = i + 1; 1966 break; 1967 } 1968 } 1969 }, 1970 1971 /** 1972 * @return {cc.ActionInterval} 1973 */ 1974 reverse:function () { 1975 var oldArray = this._animation.getFrames(); 1976 var newArray = []; 1977 cc.ArrayVerifyType(oldArray, cc.AnimationFrame); 1978 if (oldArray.length > 0) { 1979 for (var i = oldArray.length - 1; i >= 0; i--) { 1980 var element = oldArray[i]; 1981 if (!element) { 1982 break; 1983 } 1984 newArray.push(element.copy()); 1985 } 1986 } 1987 1988 var newAnim = cc.Animation.createWithAnimationFrames(newArray, this._animation.getDelayPerUnit(), this._animation.getLoops()); 1989 newAnim.setRestoreOriginalFrame(this._animation.getRestoreOriginalFrame()); 1990 return cc.Animate.create(newAnim); 1991 1992 }, 1993 1994 /** 1995 * stop the action 1996 */ 1997 stop:function () { 1998 if (this._animation.getRestoreOriginalFrame() && this._target) { 1999 this._target.setDisplayFrame(this._origFrame); 2000 } 2001 //this._super(); 2002 cc.Action.prototype.stop.call(this); 2003 } 2004 }); 2005 2006 /** 2007 * create the animate with animation 2008 * @param {cc.Animation} animation 2009 * @return {cc.Animate} 2010 * @example 2011 * // example 2012 * // create the animation with animation 2013 * var anim = cc.Animate.create(dance_grey); 2014 */ 2015 cc.Animate.create = function (animation) { 2016 var animate = new cc.Animate(); 2017 animate.initWithAnimation(animation); 2018 return animate; 2019 }; 2020 2021 /** 2022 * <p> 2023 * Overrides the target of an action so that it always runs on the target<br/> 2024 * specified at action creation rather than the one specified by runAction. 2025 * </p> 2026 * @class 2027 * @extends cc.ActionInterval 2028 */ 2029 cc.TargetedAction = cc.ActionInterval.extend(/** @lends cc.TargetedAction# */{ 2030 _action:null, 2031 _forcedTarget:null, 2032 2033 /** 2034 * Init an action with the specified action and forced target 2035 * @param {cc.Node} target 2036 * @param {cc.FiniteTimeAction} action 2037 * @return {Boolean} 2038 */ 2039 initWithTarget:function (target, action) { 2040 if (this.initWithDuration(action.getDuration())) { 2041 this._forcedTarget = target; 2042 this._action = action; 2043 return true; 2044 } 2045 return false; 2046 }, 2047 2048 startWithTarget:function (target) { 2049 //this._super(this._forcedTarget); 2050 cc.ActionInterval.prototype.startWithTarget.call(this, this._forcedTarget); 2051 this._action.startWithTarget(this._forcedTarget); 2052 }, 2053 2054 stop:function () { 2055 this._action.stop(); 2056 }, 2057 2058 update:function (time) { 2059 this._action.update(time); 2060 }, 2061 2062 /** 2063 * return the target that the action will be forced to run with 2064 * @return {cc.Node} 2065 */ 2066 getForcedTarget:function () { 2067 return this._forcedTarget; 2068 }, 2069 2070 /** 2071 * set the target that the action will be forced to run with 2072 * @param {cc.Node} forcedTarget 2073 */ 2074 setForcedTarget:function (forcedTarget) { 2075 if (this._forcedTarget != forcedTarget) { 2076 this._forcedTarget = forcedTarget; 2077 } 2078 } 2079 }); 2080 2081 /** 2082 * Create an action with the specified action and forced target 2083 * @param {cc.Node} target 2084 * @param {cc.FiniteTimeAction} action 2085 */ 2086 cc.TargetedAction.create = function (target, action) { 2087 var retObj = new cc.TargetedAction(); 2088 retObj.initWithTarget(target, action); 2089 return retObj; 2090 }; 2091