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