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