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