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