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  * cc.Waves3D action
 29  * @class
 30  * @extends cc.Grid3DAction
 31  */
 32 cc.Waves3D = cc.Grid3DAction.extend(/** @lends cc.Waves3D# */{
 33     _waves: 0,
 34     _amplitude: 0,
 35     _amplitudeRate: 0,
 36 
 37 	/**
 38 	 * Create a wave 3d action with duration, grid size, waves and amplitude
 39 	 * @param {Number} duration
 40 	 * @param {cc.Size} gridSize
 41 	 * @param {Number} waves
 42 	 * @param {Number} amplitude
 43 	 */
 44     ctor:function (duration, gridSize, waves, amplitude) {
 45         cc.GridAction.prototype.ctor.call(this);
 46 		amplitude !== undefined && this.initWithDuration(duration, gridSize, waves, amplitude);
 47     },
 48 
 49     /**
 50      * get Amplitude
 51      * @return {Number}
 52      */
 53     getAmplitude:function () {
 54         return this._amplitude;
 55     },
 56 
 57     /**
 58      * set Amplitude
 59      * @param {Number} amplitude
 60      */
 61     setAmplitude:function (amplitude) {
 62         this._amplitude = amplitude;
 63     },
 64 
 65     /**
 66      * get Amplitude Rate
 67      * @return {Number}
 68      */
 69     getAmplitudeRate:function () {
 70         return this._amplitudeRate;
 71     },
 72 
 73     /**
 74      * set Amplitude Rate
 75      * @param {Number} amplitudeRate
 76      */
 77     setAmplitudeRate:function (amplitudeRate) {
 78         this._amplitudeRate = amplitudeRate;
 79     },
 80 
 81     /**
 82      * initializes an action with duration, grid size, waves and amplitude
 83      * @param {Number} duration
 84      * @param {cc.Size} gridSize
 85      * @param {Number} waves
 86      * @param {Number} amplitude
 87      * @return {Boolean}
 88      */
 89     initWithDuration:function (duration, gridSize, waves, amplitude) {
 90         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
 91             this._waves = waves;
 92             this._amplitude = amplitude;
 93             this._amplitudeRate = 1.0;
 94             return true;
 95         }
 96         return false;
 97     },
 98 
 99     update:function (time) {
100         var locGridSize = this._gridSize;
101         var locAmplitude = this._amplitude, locPos = cc.p(0, 0);
102         var locAmplitudeRate = this._amplitudeRate, locWaves = this._waves;
103         for (var i = 0; i < locGridSize.width + 1; ++i) {
104             for (var j = 0; j < locGridSize.height + 1; ++j) {
105                 locPos.x = i;
106                 locPos.y = j;
107                 var v = this.originalVertex(locPos);
108                 v.z += (Math.sin(Math.PI * time * locWaves * 2 + (v.y + v.x) * 0.01) * locAmplitude * locAmplitudeRate);
109                 //cc.log("v.z offset is" + (Math.sin(Math.PI * time * this._waves * 2 + (v.y + v.x) * 0.01) * this._amplitude * this._amplitudeRate));
110                 this.setVertex(locPos, v);
111             }
112         }
113     }
114 });
115 
116 /**
117  * Create a wave 3d action with duration, grid size, waves and amplitude
118  * @param {Number} duration
119  * @param {cc.Size} gridSize
120  * @param {Number} waves
121  * @param {Number} amplitude
122  */
123 cc.Waves3D.create = function (duration, gridSize, waves, amplitude) {
124     return new cc.Waves3D(duration, gridSize, waves, amplitude);
125 };
126 
127 /**
128  * cc.FlipX3D action
129  * @class
130  * @extends cc.Grid3DAction
131  */
132 cc.FlipX3D = cc.Grid3DAction.extend(/** @lends cc.FlipX3D# */{
133 
134 	/**
135 	 * Create a Flip X 3D action with duration
136 	 * @constructor
137 	 * @param {Number} duration
138 	 */
139 	ctor: function(duration) {
140 		if (duration !== undefined)
141 			cc.GridAction.prototype.ctor.call(this, duration, cc.size(1, 1));
142 		else cc.GridAction.prototype.ctor.call(this);
143 	},
144 
145     /**
146      * initializes the action with duration
147      * @param {Number} duration
148      * @return {Boolean}
149      */
150     initWithDuration:function (duration) {
151         return cc.Grid3DAction.prototype.initWithDuration.call(this, duration, cc.size(1, 1));
152     },
153 
154     /**
155      * initializes the action with gridSize and duration
156      * @param {cc.Size} gridSize
157      * @param {Number} duration
158      * @return {Boolean}
159      */
160     initWithSize:function (gridSize, duration) {
161         if (gridSize.width != 1 || gridSize.height != 1) {
162             // Grid size must be (1,1)
163             cc.log("Grid size must be (1,1)");
164             return false;
165         }
166         return  cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize);
167     },
168 
169     update:function (time) {
170         var angle = Math.PI * time; // 180 degrees
171         var mz = Math.sin(angle);
172         angle = angle / 2.0; // x calculates degrees from 0 to 90
173         var mx = Math.cos(angle);
174 
175         var diff = new cc.Vertex3F();
176         var tempVer = cc.p(0, 0);
177         tempVer.x = tempVer.y = 1;
178         var v0 = this.originalVertex(tempVer);
179         tempVer.x = tempVer.y = 0;
180         var v1 = this.originalVertex(tempVer);
181 
182         var x0 = v0.x;
183         var x1 = v1.x;
184         var x;
185         var a, b, c, d;
186 
187         if (x0 > x1) {
188             // Normal Grid
189             a = cc.p(0, 0);
190             b = cc.p(0, 1);
191             c = cc.p(1, 0);
192             d = cc.p(1, 1);
193             x = x0;
194         } else {
195             // Reversed Grid
196             c = cc.p(0, 0);
197             d = cc.p(0, 1);
198             a = cc.p(1, 0);
199             b = cc.p(1, 1);
200             x = x1;
201         }
202 
203         diff.x = ( x - x * mx );
204         diff.z = Math.abs(parseFloat((x * mz) / 4.0));
205 
206         // bottom-left
207         var v = this.originalVertex(a);
208         v.x = diff.x;
209         v.z += diff.z;
210         this.setVertex(a, v);
211 
212         // upper-left
213         v = this.originalVertex(b);
214         v.x = diff.x;
215         v.z += diff.z;
216         this.setVertex(b, v);
217 
218         // bottom-right
219         v = this.originalVertex(c);
220         v.x -= diff.x;
221         v.z -= diff.z;
222         this.setVertex(c, v);
223 
224         // upper-right
225         v = this.originalVertex(d);
226         v.x -= diff.x;
227         v.z -= diff.z;
228         this.setVertex(d, v);
229     }
230 });
231 
232 /**
233  * Create a Flip X 3D action with duration
234  * @param {Number} duration
235  * @return {cc.FlipX3D}
236  */
237 cc.FlipX3D.create = function (duration) {
238     return new cc.FlipX3D(duration);
239 };
240 
241 /**
242  * cc.FlipY3D action
243  * @class
244  * @extends cc.FlipX3D
245  */
246 cc.FlipY3D = cc.FlipX3D.extend(/** @lends cc.FlipY3D# */{
247 
248 	/**
249 	 * Create a flip Y 3d action with duration
250 	 * @constructor
251 	 * @param {Number} duration
252 	 */
253 	ctor: function(duration) {
254 		if (duration !== undefined)
255 			cc.GridAction.prototype.ctor.call(this, duration, cc.size(1, 1));
256 		else cc.GridAction.prototype.ctor.call(this);
257 	},
258 
259     update:function (time) {
260         var angle = Math.PI * time; // 180 degrees
261         var mz = Math.sin(angle);
262         angle = angle / 2.0;     // x calculates degrees from 0 to 90
263         var my = Math.cos(angle);
264 
265         var diff = new cc.Vertex3F();
266 
267         var tempP = cc.p(0, 0);
268         tempP.x = tempP.y = 1;
269         var v0 = this.originalVertex(tempP);
270         tempP.x = tempP.y = 0;
271         var v1 = this.originalVertex(tempP);
272 
273         var y0 = v0.y;
274         var y1 = v1.y;
275         var y;
276         var a, b, c, d;
277 
278         if (y0 > y1) {
279             // Normal Grid
280             a = cc.p(0, 0);
281             b = cc.p(0, 1);
282             c = cc.p(1, 0);
283             d = cc.p(1, 1);
284             y = y0;
285         } else {
286             // Reversed Grid
287             b = cc.p(0, 0);
288             a = cc.p(0, 1);
289             d = cc.p(1, 0);
290             c = cc.p(1, 1);
291             y = y1;
292         }
293 
294         diff.y = y - y * my;
295         diff.z = Math.abs(parseFloat(y * mz) / 4.0);
296 
297         // bottom-left
298         var v = this.originalVertex(a);
299         v.y = diff.y;
300         v.z += diff.z;
301         this.setVertex(a, v);
302 
303         // upper-left
304         v = this.originalVertex(b);
305         v.y -= diff.y;
306         v.z -= diff.z;
307         this.setVertex(b, v);
308 
309         // bottom-right
310         v = this.originalVertex(c);
311         v.y = diff.y;
312         v.z += diff.z;
313         this.setVertex(c, v);
314 
315         // upper-right
316         v = this.originalVertex(d);
317         v.y -= diff.y;
318         v.z -= diff.z;
319         this.setVertex(d, v);
320     }
321 });
322 
323 /**
324  * Create a flip Y 3d action with duration
325  * @param {Number} duration
326  * @return {cc.FlipY3D}
327  */
328 cc.FlipY3D.create = function (duration) {
329     return new cc.FlipY3D(duration);
330 };
331 
332 /**
333  * cc.Lens3D action
334  * @class
335  * @extends cc.FlipX3D
336  */
337 cc.Lens3D = cc.Grid3DAction.extend(/** @lends cc.Lens3D# */{
338     /* lens center position */
339     _position:null,
340     _radius:0,
341     /** lens effect. Defaults to 0.7 - 0 means no effect, 1 is very strong effect */
342     _lensEffect:0,
343     /** lens is concave. (true = concave, false = convex) default is convex i.e. false */
344     _concave:false,
345     _dirty:false,
346 
347 	/**
348 	 * creates a lens 3d action with center position, radius
349 	 * @constructor
350 	 * @param {Number} duration
351 	 * @param {cc.Size} gridSize
352 	 * @param {cc.Point} position
353 	 * @param {Number} radius
354 	 */
355     ctor:function (duration, gridSize, position, radius) {
356         cc.GridAction.prototype.ctor.call(this);
357 
358         this._position = cc.p(0, 0);
359 		radius !== undefined && this.initWithDuration(duration, gridSize, position, radius);
360     },
361 
362     /**
363      * Get lens center position
364      * @return {Number}
365      */
366     getLensEffect:function () {
367         return this._lensEffect;
368     },
369 
370     /**
371      * Set lens center position
372      * @param {Number} lensEffect
373      */
374     setLensEffect:function (lensEffect) {
375         this._lensEffect = lensEffect;
376     },
377 
378     /**
379      * Set whether lens is concave
380      * @param {Boolean} concave
381      */
382     setConcave:function (concave) {
383         this._concave = concave;
384     },
385 
386     /**
387      * get Position
388      * @return {cc.Point}
389      */
390     getPosition:function () {
391         return this._position;
392     },
393 
394     /**
395      * set Position
396      * @param {cc.Point} position
397      */
398     setPosition:function (position) {
399         if (!cc.pointEqualToPoint(position, this._position)) {
400             this._position.x = position.x;
401             this._position.y = position.y;
402             this._dirty = true;
403         }
404     },
405 
406     /**
407      * initializes the action with center position, radius, a grid size and duration
408      * @param {Number} duration
409      * @param {cc.Size} gridSize
410      * @param {cc.Point} position
411      * @param {Number} radius
412      * @return {Boolean}
413      */
414     initWithDuration:function (duration, gridSize, position, radius) {
415         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
416             this.setPosition(position);
417             this._radius = radius;
418             this._lensEffect = 0.7;
419             this._dirty = true;
420             return true;
421         }
422         return false;
423     },
424 
425     update:function (time) {
426         if (this._dirty) {
427             var locGridSizeWidth = this._gridSize.width, locGridSizeHeight = this._gridSize.height;
428             var locRadius = this._radius, locLensEffect = this._lensEffect;
429             var locPos = cc.p(0, 0);
430             var vect = cc.p(0, 0);
431             var v, r, l, new_r, pre_log;
432             for (var i = 0; i < locGridSizeWidth + 1; ++i) {
433                 for (var j = 0; j < locGridSizeHeight + 1; ++j) {
434                     locPos.x = i;
435                     locPos.y = j;
436                     v = this.originalVertex(locPos);
437                     vect.x = this._position.x - v.x;
438                     vect.y = this._position.y - v.y;
439                     r = cc.pLength(vect);
440 
441                     if (r < locRadius) {
442                         r = locRadius - r;
443                         pre_log = r / locRadius;
444                         if (pre_log == 0)
445                             pre_log = 0.001;
446 
447                         l = Math.log(pre_log) * locLensEffect;
448                         new_r = Math.exp(l) * locRadius;
449 
450                         r = cc.pLength(vect);
451                         if (r > 0) {
452                             vect.x = vect.x / r;
453                             vect.y = vect.y / r;
454 
455                             vect.x = vect.x * new_r;
456                             vect.y = vect.y * new_r;
457                             v.z += cc.pLength(vect) * locLensEffect;
458                         }
459                     }
460                     this.setVertex(locPos, v);
461                 }
462             }
463             this._dirty = false;
464         }
465     }
466 });
467 
468 /**
469  * creates a lens 3d action with center position, radius
470  * @param {Number} duration
471  * @param {cc.Size} gridSize
472  * @param {cc.Point} position
473  * @param {Number} radius
474  * @return {cc.Lens3D}
475  */
476 cc.Lens3D.create = function (duration, gridSize, position, radius) {
477     return new cc.Lens3D(duration, gridSize, position, radius);
478 };
479 
480 /**
481  * cc.Ripple3D action
482  * @class
483  * @extends cc.Grid3DAction
484  */
485 cc.Ripple3D = cc.Grid3DAction.extend(/** @lends cc.Ripple3D# */{
486     /* center position */
487     _position: null,
488     _radius: 0,
489     _waves: 0,
490     _amplitude: 0,
491     _amplitudeRate: 0,
492 
493 	/**
494 	 * creates a ripple 3d action with radius, number of waves, amplitude
495 	 * @constructor
496 	 * @param {Number} duration
497 	 * @param {cc.Size} gridSize
498 	 * @param {cc.Point} position
499 	 * @param {Number} radius
500 	 * @param {Number} waves
501 	 * @param {Number} amplitude
502 	 */
503     ctor:function (duration, gridSize, position, radius, waves, amplitude) {
504         cc.GridAction.prototype.ctor.call(this);
505 
506         this._position = cc.p(0, 0);
507 		amplitude !== undefined && this.initWithDuration(duration, gridSize, position, radius, waves, amplitude);
508     },
509 
510     /**
511      * get center position
512      * @return {cc.Point}
513      */
514     getPosition:function () {
515         return this._position;
516     },
517 
518     /**
519      * set center position
520      * @param {cc.Point} position
521      */
522     setPosition:function (position) {
523         this._position.x = position.x;
524         this._position.y = position.y;
525     },
526 
527     /**
528      * get Amplitude
529      * @return {Number}
530      */
531     getAmplitude:function () {
532         return this._amplitude;
533     },
534 
535     /**
536      * set Amplitude
537      * @param {Number} amplitude
538      */
539     setAmplitude:function (amplitude) {
540         this._amplitude = amplitude;
541     },
542 
543     /**
544      * get Amplitude rate
545      * @return {*}
546      */
547     getAmplitudeRate:function () {
548         return this._amplitudeRate;
549     },
550 
551     /**
552      * get amplitude rate
553      * @param {Number} amplitudeRate
554      */
555     setAmplitudeRate:function (amplitudeRate) {
556         this._amplitudeRate = amplitudeRate;
557     },
558 
559     /**
560      * initializes the action with radius, number of waves, amplitude, a grid size and duration
561      * @param {Number} duration
562      * @param {cc.Size} gridSize
563      * @param {cc.Point} position
564      * @param {Number} radius
565      * @param {Number} waves
566      * @param {Number} amplitude
567      * @return {Boolean}
568      */
569     initWithDuration:function (duration, gridSize, position, radius, waves, amplitude) {
570         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
571             this.setPosition(position);
572             this._radius = radius;
573             this._waves = waves;
574             this._amplitude = amplitude;
575             this._amplitudeRate = 1.0;
576             return true;
577         }
578         return false;
579     },
580 
581     update:function (time) {
582         var locGridSizeWidth = this._gridSize.width, locGridSizeHeight = this._gridSize.height;
583         var locPos = cc.p(0, 0), locRadius = this._radius;
584         var locWaves = this._waves, locAmplitude = this._amplitude, locAmplitudeRate = this._amplitudeRate;
585         var v, r, tempPos = cc.p(0, 0);
586         for (var i = 0; i < (locGridSizeWidth + 1); ++i) {
587             for (var j = 0; j < (locGridSizeHeight + 1); ++j) {
588                 locPos.x = i;
589                 locPos.y = j;
590                 v = this.originalVertex(locPos);
591 
592                 tempPos.x = this._position.x - v.x;
593                 tempPos.y = this._position.y - v.y;
594                 r = cc.pLength(tempPos);
595 
596                 if (r < locRadius) {
597                     r = locRadius - r;
598                     var rate = Math.pow(r / locRadius, 2);
599                     v.z += (Math.sin(time * Math.PI * locWaves * 2 + r * 0.1) * locAmplitude * locAmplitudeRate * rate);
600                 }
601                 this.setVertex(locPos, v);
602             }
603         }
604     }
605 });
606 
607 /**
608  * creates a ripple 3d action with radius, number of waves, amplitude
609  * @param {Number} duration
610  * @param {cc.Size} gridSize
611  * @param {cc.Point} position
612  * @param {Number} radius
613  * @param {Number} waves
614  * @param {Number} amplitude
615  * @return {cc.Ripple3D}
616  */
617 cc.Ripple3D.create = function (duration, gridSize, position, radius, waves, amplitude) {
618     return new cc.Ripple3D(duration, gridSize, position, radius, waves, amplitude);
619 };
620 
621 /**
622  * cc.Shaky3D action
623  * @class
624  * @extends cc.Grid3DAction
625  */
626 cc.Shaky3D = cc.Grid3DAction.extend(/** @lends cc.Shaky3D# */{
627     _randRange: 0,
628     _shakeZ: false,
629 
630 	/**
631 	 * Create a shaky3d action with a range, shake Z vertices
632 	 * @constructor
633 	 * @param {Number} duration
634 	 * @param {cc.Size} gridSize
635 	 * @param {Number} range
636 	 * @param {Boolean} shakeZ
637 	 */
638     ctor:function (duration, gridSize, range, shakeZ) {
639         cc.GridAction.prototype.ctor.call(this);
640 		shakeZ !== undefined && this.initWithDuration(duration, gridSize, range, shakeZ);
641     },
642 
643     /**
644      * initializes the action with a range, shake Z vertices, a grid and duration
645      * @param {Number} duration
646      * @param {cc.Size} gridSize
647      * @param {Number} range
648      * @param {Boolean} shakeZ
649      * @return {Boolean}
650      */
651     initWithDuration:function (duration, gridSize, range, shakeZ) {
652         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
653             this._randRange = range;
654             this._shakeZ = shakeZ;
655             return true;
656         }
657         return false;
658     },
659 
660     update:function (time) {
661         var locGridSizeWidth = this._gridSize.width, locGridSizeHeight = this._gridSize.height;
662         var locRandRange = this._randRange, locShakeZ = this._shakeZ, locP = cc.p(0, 0);
663         var v;
664         for (var i = 0; i < (locGridSizeWidth + 1); ++i) {
665             for (var j = 0; j < (locGridSizeHeight + 1); ++j) {
666                 locP.x = i;
667                 locP.y = j;
668                 v = this.originalVertex(locP);
669                 v.x += (cc.rand() % (locRandRange * 2)) - locRandRange;
670                 v.y += (cc.rand() % (locRandRange * 2)) - locRandRange;
671                 if (locShakeZ)
672                     v.z += (cc.rand() % (locRandRange * 2)) - locRandRange;
673                 this.setVertex(locP, v);
674             }
675         }
676     }
677 });
678 
679 /**
680  * creates the action with a range, shake Z vertices, a grid and duration
681  * @param {Number} duration
682  * @param {cc.Size} gridSize
683  * @param {Number} range
684  * @param {Boolean} shakeZ
685  * @return {cc.Shaky3D}
686  */
687 cc.Shaky3D.create = function (duration, gridSize, range, shakeZ) {
688     return new cc.Shaky3D(duration, gridSize, range, shakeZ);
689 };
690 
691 /**
692  * cc.Liquid action
693  * @class
694  * @extends cc.Grid3DAction
695  */
696 cc.Liquid = cc.Grid3DAction.extend(/** @lends cc.Liquid# */{
697     _waves: 0,
698     _amplitude: 0,
699     _amplitudeRate: 0,
700 
701 	/**
702 	 * Create a liquid action with amplitude, a grid and duration
703 	 *
704 	 * @constructor
705 	 * @param {Number} duration
706 	 * @param {cc.Size} gridSize
707 	 * @param {Number} waves
708 	 * @param {Number} amplitude
709 	 */
710     ctor: function (duration, gridSize, waves, amplitude) {
711         cc.GridAction.prototype.ctor.call(this);
712 		amplitude !== undefined && this.initWithDuration(duration, gridSize, waves, amplitude);
713     },
714 
715     /**
716      * get amplitude
717      * @return {Number}
718      */
719     getAmplitude:function () {
720         return this._amplitude;
721     },
722 
723     /**
724      * set amplitude
725      * @param {Number} amplitude
726      */
727     setAmplitude:function (amplitude) {
728         this._amplitude = amplitude;
729     },
730 
731     /**
732      * get amplitude rate
733      * @return {Number}
734      */
735     getAmplitudeRate:function () {
736         return this._amplitudeRate;
737     },
738 
739     /**
740      * set amplitude rate
741      * @param {Number} amplitudeRate
742      */
743     setAmplitudeRate:function (amplitudeRate) {
744         this._amplitudeRate = amplitudeRate;
745     },
746 
747     /**
748      * initializes the action with amplitude, a grid and duration
749      * @param {Number} duration
750      * @param {cc.Size} gridSize
751      * @param {Number} waves
752      * @param {Number} amplitude
753      * @return {Boolean}
754      */
755     initWithDuration:function (duration, gridSize, waves, amplitude) {
756         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
757             this._waves = waves;
758             this._amplitude = amplitude;
759             this._amplitudeRate = 1.0;
760             return true;
761         }
762         return false;
763     },
764 
765     update:function (time) {
766         var locSizeWidth = this._gridSize.width, locSizeHeight = this._gridSize.height, locPos = cc.p(0, 0);
767         var locWaves = this._waves, locAmplitude = this._amplitude, locAmplitudeRate = this._amplitudeRate;
768         var v;
769         for (var i = 1; i < locSizeWidth; ++i) {
770             for (var j = 1; j < locSizeHeight; ++j) {
771                 locPos.x = i;
772                 locPos.y = j;
773                 v = this.originalVertex(locPos);
774                 v.x = (v.x + (Math.sin(time * Math.PI * locWaves * 2 + v.x * .01) * locAmplitude * locAmplitudeRate));
775                 v.y = (v.y + (Math.sin(time * Math.PI * locWaves * 2 + v.y * .01) * locAmplitude * locAmplitudeRate));
776                 this.setVertex(locPos, v);
777             }
778         }
779     }
780 });
781 
782 /**
783  * creates the action with amplitude, a grid and duration
784  * @param {Number} duration
785  * @param {cc.Size} gridSize
786  * @param {Number} waves
787  * @param {Number} amplitude
788  * @return {cc.Liquid}
789  */
790 cc.Liquid.create = function (duration, gridSize, waves, amplitude) {
791     return new cc.Liquid(duration, gridSize, waves, amplitude);
792 };
793 
794 /**
795  * cc.Waves action
796  * @class
797  * @extends cc.Grid3DAction
798  */
799 cc.Waves = cc.Grid3DAction.extend(/** @lends cc.Waves# */{
800     _waves: 0,
801     _amplitude: 0,
802     _amplitudeRate: 0,
803     _vertical: false,
804     _horizontal: false,
805 
806 	/**
807 	 * Create a wave action with amplitude, horizontal sin, vertical sin, a grid and duration
808 	 *
809 	 * @constructor
810 	 * @param {Number} duration
811 	 * @param {cc.Size} gridSize
812 	 * @param {Number} waves
813 	 * @param {Number} amplitude
814 	 * @param {Boolean} horizontal
815 	 * @param {Boolean} vertical
816 	 */
817     ctor: function (duration, gridSize, waves, amplitude, horizontal, vertical) {
818         cc.GridAction.prototype.ctor.call(this);
819 		vertical !== undefined && this.initWithDuration(duration, gridSize, waves, amplitude, horizontal, vertical);
820     },
821 
822     /**
823      * get amplitude
824      * @return {Number}
825      */
826     getAmplitude:function () {
827         return this._amplitude;
828     },
829 
830     /**
831      * set amplitude
832      * @param {Number} amplitude
833      */
834     setAmplitude:function (amplitude) {
835         this._amplitude = amplitude;
836     },
837 
838     /**
839      * get amplitude rate
840      * @return {Number}
841      */
842     getAmplitudeRate:function () {
843         return this._amplitudeRate;
844     },
845 
846     /**
847      * set amplitude rate
848      * @param {Number} amplitudeRate
849      */
850     setAmplitudeRate:function (amplitudeRate) {
851         this._amplitudeRate = amplitudeRate;
852     },
853 
854     /**
855      * initializes the action with amplitude, horizontal sin, vertical sin, a grid and duration
856      * @param {Number} duration
857      * @param {cc.Size} gridSize
858      * @param {Number} waves
859      * @param {Number} amplitude
860      * @param {Boolean} horizontal
861      * @param {Boolean} vertical
862      * @return {Boolean}
863      */
864     initWithDuration:function (duration, gridSize, waves, amplitude, horizontal, vertical) {
865         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
866             this._waves = waves;
867             this._amplitude = amplitude;
868             this._amplitudeRate = 1.0;
869             this._horizontal = horizontal;
870             this._vertical = vertical;
871             return true;
872         }
873         return false;
874     },
875 
876     update:function (time) {
877         var locSizeWidth = this._gridSize.width, locSizeHeight = this._gridSize.height, locPos = cc.p(0, 0);
878         var locVertical = this._vertical, locHorizontal = this._horizontal;
879         var locWaves = this._waves, locAmplitude = this._amplitude, locAmplitudeRate = this._amplitudeRate;
880         var v;
881         for (var i = 0; i < locSizeWidth + 1; ++i) {
882             for (var j = 0; j < locSizeHeight + 1; ++j) {
883                 locPos.x = i;
884                 locPos.y = j;
885                 v = this.originalVertex(locPos);
886                 if (locVertical)
887                     v.x = (v.x + (Math.sin(time * Math.PI * locWaves * 2 + v.y * .01) * locAmplitude * locAmplitudeRate));
888                 if (locHorizontal)
889                     v.y = (v.y + (Math.sin(time * Math.PI * locWaves * 2 + v.x * .01) * locAmplitude * locAmplitudeRate));
890                 this.setVertex(locPos, v);
891             }
892         }
893     }
894 });
895 
896 /**
897  * initializes the action with amplitude, horizontal sin, vertical sin, a grid and duration
898  * @param {Number} duration
899  * @param {cc.Size} gridSize
900  * @param {Number} waves
901  * @param {Number} amplitude
902  * @param {Boolean} horizontal
903  * @param {Boolean} vertical
904  * @return {cc.Waves}
905  */
906 cc.Waves.create = function (duration, gridSize, waves, amplitude, horizontal, vertical) {
907     return new cc.Waves(duration, gridSize, waves, amplitude, horizontal, vertical);
908 };
909 
910 /** @brief  */
911 /**
912  * cc.Twirl action
913  * @class
914  * @extends cc.Grid3DAction
915  */
916 cc.Twirl = cc.Grid3DAction.extend(/** @lends cc.Twirl# */{
917     /* twirl center */
918     _position: null,
919     _twirls: 0,
920     _amplitude: 0,
921     _amplitudeRate: 0,
922 
923 	/**
924 	 * Create a grid 3d action with center position, number of twirls, amplitude, a grid size and duration
925 	 *
926 	 * @constructor
927 	 * @param {Number} duration
928 	 * @param {cc.Size} gridSize
929 	 * @param {cc.Point} position
930 	 * @param {Number} twirls
931 	 * @param {Number} amplitude
932 	 */
933     ctor:function (duration, gridSize, position, twirls, amplitude) {
934         cc.GridAction.prototype.ctor.call(this);
935 
936         this._position = cc.p(0, 0);
937 		amplitude !== undefined && this.initWithDuration(duration, gridSize, position, twirls, amplitude);
938     },
939 
940     /**
941      * get twirl center
942      * @return {cc.Point}
943      */
944     getPosition:function () {
945         return this._position;
946     },
947 
948     /**
949      * set twirl center
950      * @param {cc.Point} position
951      */
952     setPosition:function (position) {
953         this._position.x = position.x;
954         this._position.y = position.y;
955     },
956 
957     /**
958      * get amplitude
959      * @return {Number}
960      */
961     getAmplitude:function () {
962         return this._amplitude;
963     },
964 
965     /**
966      * set amplitude
967      * @param {Number} amplitude
968      */
969     setAmplitude:function (amplitude) {
970         this._amplitude = amplitude;
971     },
972 
973     /**
974      * get amplitude rate
975      * @return {Number}
976      */
977     getAmplitudeRate:function () {
978         return this._amplitudeRate;
979     },
980 
981     /**
982      * set amplitude rate
983      * @param {Number} amplitudeRate
984      */
985     setAmplitudeRate:function (amplitudeRate) {
986         this._amplitudeRate = amplitudeRate;
987     },
988 
989     /** initializes the action with center position, number of twirls, amplitude, a grid size and duration */
990     initWithDuration:function (duration, gridSize, position, twirls, amplitude) {
991         if (cc.Grid3DAction.prototype.initWithDuration.call(this, duration, gridSize)) {
992             this.setPosition(position);
993             this._twirls = twirls;
994             this._amplitude = amplitude;
995             this._amplitudeRate = 1.0;
996             return true;
997         }
998         return false;
999     },
1000 
1001     update:function (time) {
1002         var c = this._position;
1003         var locSizeWidth = this._gridSize.width, locSizeHeight = this._gridSize.height, locPos = cc.p(0, 0);
1004         var amp = 0.1 * this._amplitude * this._amplitudeRate;
1005         var locTwirls = this._twirls;
1006         var v, a, dX, dY, avg = cc.p(0, 0);
1007         for (var i = 0; i < (locSizeWidth + 1); ++i) {
1008             for (var j = 0; j < (locSizeHeight + 1); ++j) {
1009                 locPos.x = i;
1010                 locPos.y = j;
1011                 v = this.originalVertex(locPos);
1012 
1013                 avg.x = i - (locSizeWidth / 2.0);
1014                 avg.y = j - (locSizeHeight / 2.0);
1015 
1016                 a = cc.pLength(avg) * Math.cos(Math.PI / 2.0 + time * Math.PI * locTwirls * 2) * amp;
1017 
1018                 dX = Math.sin(a) * (v.y - c.y) + Math.cos(a) * (v.x - c.x);
1019                 dY = Math.cos(a) * (v.y - c.y) - Math.sin(a) * (v.x - c.x);
1020 
1021                 v.x = c.x + dX;
1022                 v.y = c.y + dY;
1023 
1024                 this.setVertex(locPos, v);
1025             }
1026         }
1027     }
1028 });
1029 
1030 /**
1031  * creates the action with center position, number of twirls, amplitude, a grid size and duration
1032  * @param {Number} duration
1033  * @param {cc.Size} gridSize
1034  * @param {cc.Point} position
1035  * @param {Number} twirls
1036  * @param {Number} amplitude
1037  * @return {cc.Twirl}
1038  */
1039 cc.Twirl.create = function (duration, gridSize, position, twirls, amplitude) {
1040     return new cc.Twirl(duration, gridSize, position, twirls, amplitude);
1041 };
1042