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 var cc = cc = cc || {};
 28 
 29 /**
 30  @brief cc.Waves3D action
 31  */
 32 cc.Waves3D = cc.Grid3DAction.extend({
 33     _waves:null,
 34     _amplitude:null,
 35     _amplitudeRate:null,
 36     getAmplitude:function () {
 37         return this._amplitude;
 38     },
 39     setAmplitude:function (amplitude) {
 40         this._amplitude = amplitude;
 41     },
 42 
 43     getAmplitudeRate:function () {
 44         return this._amplitudeRate;
 45     },
 46     setAmplitudeRate:function (amplitudeRate) {
 47         this._amplitudeRate = amplitudeRate;
 48     },
 49 
 50     /** init the action */
 51     initWithWaves:function (wav, amp, gridSize, duration) {
 52         if (cc.Grid3DAction.initWithSize(gridSize, duration)) {
 53             this._waves = wav;
 54             this._amplitude = amp;
 55             this._amplitudeRate = 1.0;
 56 
 57             return true;
 58         }
 59 
 60         return false;
 61     },
 62 
 63     copyWithZone:function (zone) {
 64         var newZone = null;
 65         var copy = null;
 66         if (zone && zone.copyObject) {
 67             //in case of being called at sub class
 68             copy = zone.copyObject;
 69         }
 70         else {
 71             copy = new cc.Waves3D();
 72             zone = newZone = new cc.Zone(copy);
 73         }
 74 
 75         cc.Grid3DAction.copyWithZone(zone);
 76 
 77 
 78         copy.initWithWaves(this._waves, this._amplitude, this._gridSize, this.duration);
 79 
 80         return copy;
 81     },
 82     update:function (time) {
 83         var i, j;
 84         for (i = 0; i < this._gridSize.x + 1; ++i) {
 85             for (j = 0; j < this._gridSize.y + 1; ++j) {
 86                 var v = this.originalVertex(cc.g(i, j));
 87                 v.z += (Math.sin(Math.PI * time * this._waves * 2 + (v.y + v.x) * .01) * this._amplitude * this._amplitudeRate);
 88                 cc.log("v.z offset is" + (Math.sin(Math.PI * time * this._waves * 2 + (v.y + v.x) * .01) * this._amplitude * this._amplitudeRate));
 89                 this.setVertex(cc.g(i, j), v);
 90             }
 91         }
 92     }
 93 });
 94 
 95 /** create the action */
 96 cc.Waves3D.create = function (wav, amp, gridSize, duration) {
 97     var action = new cc.Waves3D();
 98     return action;
 99 };
100 
101 /** @brief cc.FlipX3D action */
102 cc.FlipX3D = cc.Grid3DAction({
103     /** initializes the action with duration */
104     initWithDuration:function (duration) {
105         return cc.Grid3DAction.initWithSize(cc.g(1, 1), duration);
106     },
107     initWithSize:function (gridSize, duration) {
108         if (gridSize.x != 1 || gridSize.y != 1) {
109             // Grid size must be (1,1)
110             cc.Assert(0, "");
111 
112             return false;
113         }
114 
115         return cc.Grid3DAction.initWithSize(gridSize, duration);
116     },
117     copyWithZone:function (zone) {
118         var newZone = null;
119         var copy = null;
120         if (zone && zone.copyObject) {
121             //in case of being called at sub class
122             copy = zone.copyObject;
123         }
124         else {
125             copy = new cc.FlipX3D();
126             zone = newZone = new cc.Zone(copy);
127         }
128 
129         cc.Grid3DAction.copyWithZone(zone);
130 
131         copy.initWithSize(this._gridSize, this.duration);
132 
133         return copy;
134     },
135     update:function (time) {
136         var angle = Math.PI * time; // 180 degrees
137         var mz = Math.sin(angle);
138         angle = angle / 2.0; // x calculates degrees from 0 to 90
139         var mx = Math.cos(angle);
140 
141         var v0, v1, v, diff;
142 
143         v0 = this.originalVertex(cc.g(1, 1));
144         v1 = this.originalVertex(cc.g(0, 0));
145 
146         var x0 = v0.x;
147         var x1 = v1.x;
148         var x;
149         var a, b, c, d;
150 
151         if (x0 > x1) {
152             // Normal Grid
153             a = cc.g(0, 0);
154             b = cc.g(0, 1);
155             c = cc.g(1, 0);
156             d = cc.g(1, 1);
157             x = x0;
158         }
159         else {
160             // Reversed Grid
161             c = cc.g(0, 0);
162             d = cc.g(0, 1);
163             a = cc.g(1, 0);
164             b = cc.g(1, 1);
165             x = x1;
166         }
167 
168         diff.x = ( x - x * mx );
169         diff.z = Math.abs(parseFloat((x * mz) / 4.0));
170 
171         // bottom-left
172         v = this.originalVertex(a);
173         v.x = diff.x;
174         v.z += diff.z;
175         this.setVertex(a, v);
176 
177         // upper-left
178         v = this.originalVertex(b);
179         v.x = diff.x;
180         v.z += diff.z;
181         this.setVertex(b, v);
182 
183         // bottom-right
184         v = this.originalVertex(c);
185         v.x -= diff.x;
186         v.z -= diff.z;
187         this.setVertex(c, v);
188 
189         // upper-right
190         v = this.originalVertex(d);
191         v.x -= diff.x;
192         v.z -= diff.z;
193         this.setVertex(d, v);
194     }
195 
196 });
197 
198 /** creates the action with duration */
199 cc.FlipX3D.create = function (duration) {
200     var action = new cc.FlipX3D();
201     return action;
202 };
203 
204 /** @brief cc.FlipY3D action */
205 cc.FlipY3D = cc.FlipX3D.extend({
206     update:function (time) {
207         var angle = Math.PI * time; // 180 degrees
208         var mz = Math.sin(angle);
209         angle = angle / 2.0;     // x calculates degrees from 0 to 90
210         var my = Math.cos(angle);
211 
212         var v0, v1, v, diff;
213 
214         v0 = this.originalVertex(cc.g(1, 1));
215         v1 = this.originalVertex(cc.g(0, 0));
216 
217         var y0 = v0.y;
218         var y1 = v1.y;
219         var y;
220         var a, b, c, d;
221 
222         if (y0 > y1) {
223             // Normal Grid
224             a = cc.g(0, 0);
225             b = cc.g(0, 1);
226             c = cc.g(1, 0);
227             d = cc.g(1, 1);
228             y = y0;
229         }
230         else {
231             // Reversed Grid
232             b = cc.g(0, 0);
233             a = cc.g(0, 1);
234             d = cc.g(1, 0);
235             c = cc.g(1, 1);
236             y = y1;
237         }
238 
239         diff.y = y - y * my;
240         diff.z = Math.abs(parseFloat(y * mz) / 4.0);
241 
242         // bottom-left
243         v = this.originalVertex(a);
244         v.y = diff.y;
245         v.z += diff.z;
246         this.setVertex(a, v);
247 
248         // upper-left
249         v = this.originalVertex(b);
250         v.y -= diff.y;
251         v.z -= diff.z;
252         this.setVertex(b, v);
253 
254         // bottom-right
255         v = this.originalVertex(c);
256         v.y = diff.y;
257         v.z += diff.z;
258         this.setVertex(c, v);
259 
260         // upper-right
261         v = this.originalVertex(d);
262         v.y -= diff.y;
263         v.z -= diff.z;
264         this.setVertex(d, v);
265     },
266     copyWithZone:function (zone) {
267         var newZone = null;
268         var copy = null;
269         if (zone && zone.copyObject) {
270             //in case of being called at sub class
271             copy = zone.copyObject;
272         }
273         else {
274             copy = new cc.FlipY3D();
275             zone = newZone = new cc.Zone(copy);
276         }
277 
278         cc.FlipX3D.copyWithZone(zone);
279 
280         copy.initWithSize(this._gridSize, this.duration);
281 
282         return copy;
283     }
284 });
285 
286 /** creates the action with duration */
287 cc.FlipY3D.create = function (duration) {
288     var action = new cc.FlipY3D();
289     return action;
290 };
291 
292 /** @brief cc.Lens3D action */
293 cc.Lens3D = cc.Grid3DAction.extend({
294     /* lens center position */
295     _position:null,
296     _radius:null,
297     /** lens effect. Defaults to 0.7 - 0 means no effect, 1 is very strong effect */
298     _lensEffect:null,
299 
300     /* @since v0.99.5 */
301 // cc.Point this.lastPosition;
302     _positionInPixels:null,
303     _dirty:null,
304     /** Get lens center position */
305     getLensEffect:function () {
306         return this._lensEffect;
307     },
308     /** Set lens center position */
309     setLensEffect:function (lensEffect) {
310         this._lensEffect = lensEffect;
311     },
312 
313     getPosition:function () {
314         return this._position;
315     },
316     setPosition:function (pos) {
317         if (!cc.Point.CCPointEqualToPoint(pos, this._position)) {
318             this._position = pos;
319             this._positionInPixels.x = pos.x * cc.CONTENT_SCALE_FACTOR();
320             this._positionInPixels.y = pos.y * cc.CONTENT_SCALE_FACTOR();
321 
322             this._dirty = true;
323         }
324     },
325 
326     /** initializes the action with center position, radius, a grid size and duration */
327     initWithPosition:function (pos, r, gridSize, duration) {
328         if (cc.Grid3DAction.initWithSize(gridSize, duration)) {
329             this._position = cc.p(-1, -1);
330             this.setPosition(pos);
331             this._radius = r;
332             this._lensEffect = 0.7;
333             this._dirty = true;
334 
335             return true;
336         }
337 
338         return false;
339     },
340     copyWithZone:function (zone) {
341         var newZone = null;
342         var copy = null;
343         if (zone && zone.copyObject) {
344             //in case of being called at sub class
345             copy = zone.copyObject;
346         }
347         else {
348             copy = new cc.Lens3D();
349             zone = newZone = new cc.Zone(copy);
350         }
351 
352         cc.Grid3DAction.copyWithZone(zone);
353 
354         copy.initWithPosition(this._position, this._radius, this._gridSize, this.duration);
355 
356         return copy;
357     },
358     update:function (time) {
359         if (this._dirty) {
360             var i, j;
361 
362             for (i = 0; i < this._gridSize.x + 1; ++i) {
363                 for (j = 0; j < this._gridSize.y + 1; ++j) {
364                     var v = this.originalVertex(cc.g(i, j));
365                     var vect = cc.pSub(this._positionInPixels, ccp(v.x, v.y));
366                     var r = cc.pLength(vect);
367 
368                     if (r < this._radius) {
369                         r = this._radius - r;
370                         var pre_log = r / this._radius;
371                         if (pre_log == 0) {
372                             pre_log = 0.001;
373                         }
374 
375                         var l = Math.log(pre_log) * this._lensEffect;
376                         var new_r = Math.exp(l) * this._radius;
377 
378                         if (cc.pLength(vect) > 0) {
379                             vect = cc.pNormalize(vect);
380                             var new_vect = cc.pMult(vect, new_r);
381                             v.z += cc.pLength(new_vect) * this._lensEffect;
382                         }
383                     }
384 
385                     this.setVertex(cc.g(i, j), v);
386                 }
387             }
388 
389             this._dirty = false;
390         }
391     }
392 });
393 
394 /** creates the action with center position, radius, a grid size and duration */
395 cc.Lens3D.create = function (pos, r, gridSize, duration) {
396     var action = new cc.Lens3D();
397     return action;
398 };
399 
400 /** @brief cc.Ripple3D action */
401 cc.Ripple3D = cc.Grid3DAction.extend({
402     /* center position */
403     _position:null,
404     _radius:null,
405     _waves:null,
406     _amplitude:null,
407     _amplitudeRate:null,
408 
409     /*@since v0.99.5*/
410     _positionInPixels:null,
411     /** get center position */
412     getPosition:function () {
413         return this._position;
414     },
415     /** set center position */
416     setPosition:function (position) {
417         this._position = position;
418         this._positionInPixels.x = position.x * cc.CONTENT_SCALE_FACTOR();
419         this._positionInPixels.y = position.y * cc.CONTENT_SCALE_FACTOR();
420     },
421 
422     getAmplitude:function () {
423         return this._amplitude;
424     },
425     setAmplitude:function (amplitude) {
426         this._amplitude = amplitude;
427     },
428 
429     getAmplitudeRate:function () {
430         return this._amplitudeRate;
431     },
432     setAmplitudeRate:function (amplitudeRate) {
433         this._amplitudeRate = amplitudeRate;
434     },
435 
436     /** initializes the action with radius, number of waves, amplitude, a grid size and duration */
437     initWithPosition:function (pos, r, wav, amp, gridSize, duration) {
438         if (cc.Grid3DAction.initWithSize(gridSize, duration)) {
439             this.setPosition(pos);
440             this._radius = r;
441             this._waves = wav;
442             this._amplitude = amp;
443             this._amplitudeRate = 1.0;
444 
445             return true;
446         }
447 
448         return false;
449     },
450     copyWithZone:function (zone) {
451         var newZone = null;
452         varcopy = null;
453         if (zone && zone.copyObject) {
454             //in case of being called at sub class
455             copy = zone.copyObject;
456         }
457         else {
458             copy = new cc.Ripple3D();
459             zone = newZone = new cc.Zone(copy);
460         }
461 
462         cc.Grid3DAction.copyWithZone(zone);
463 
464         copy.initWithPosition(this._position, this._radius, this._waves, this._amplitude, this._gridSize, this.duration);
465 
466         return copy;
467     },
468     update:function (time) {
469         var i, j;
470 
471         for (i = 0; i < (this._gridSize.x + 1); ++i) {
472             for (j = 0; j < (this._gridSize.y + 1); ++j) {
473                 var v = this.originalVertex(cc.g(i, j));
474                 var vect = cc.pSub(this._positionInPixels, ccp(v.x, v.y));
475                 var r = cc.pLength(vect);
476 
477                 if (r < this._radius) {
478                     r = this._radius - r;
479                     var rate = Math.pow(r / this._radius, 2);
480                     v.z += (Math.sin(time * Math.PI * this._waves * 2 + r * 0.1) * this._amplitude * this._amplitudeRate * rate);
481                 }
482 
483                 this.setVertex(cc.g(i, j), v);
484             }
485         }
486     }
487 });
488 /** creates the action with radius, number of waves, amplitude, a grid size and duration */
489 cc.Ripple3D.create = function (pos, r, wav, amp, gridSize, duration) {
490     var action = new cc.Ripple3D();
491     return action;
492 };
493 
494 
495 /** @brief cc.Shaky3D action */
496 cc.Shaky3D = cc.Grid3DAction.extend({
497     _randrange:null,
498     _shakeZ:null,
499     /** initializes the action with a range, shake Z vertices, a grid and duration */
500     initWithRange:function (range, shakeZ, gridSize, duration) {
501         if (cc.Grid3DAction.initWithSize(gridSize, duration)) {
502             this._randrange = range;
503             this._shakeZ = shakeZ;
504 
505             return true;
506         }
507 
508         return false;
509     },
510     copyWithZone:function (zone) {
511         var newZone = null;
512         var copy = null;
513         if (zone && zone.copyObject) {
514             //in case of being called at sub class
515             copy = zone.copyObject;
516         }
517         else {
518             copy = new cc.Shaky3D();
519             zone = newZone = new cc.Zone(copy);
520         }
521 
522         cc.Grid3DAction.copyWithZone(zone);
523 
524         copy.initWithRange(this._randrange, this._shakeZ, this._gridSize, this.duration);
525 
526         return copy;
527     },
528     update:function (time) {
529         var i, j;
530 
531         for (i = 0; i < (this._gridSize.x + 1); ++i) {
532             for (j = 0; j < (this._gridSize.y + 1); ++j) {
533                 var v = this.originalVertex(cc.g(i, j));
534                 v.x += (Math.random() % (this._randrange * 2)) - this._randrange;
535                 v.y += (Math.random() % (this._randrange * 2)) - this._randrange;
536                 if (this._shakeZ) {
537                     v.z += (Math.random() % (this._randrange * 2)) - this._randrange;
538                 }
539 
540                 this.setVertex(cc.g(i, j), v);
541             }
542         }
543     }
544 });
545 
546 /** creates the action with a range, shake Z vertices, a grid and duration */
547 cc.Shaky3D.create = function (range, shakeZ, gridSize, duration) {
548     var action = new cc.Shaky3D();
549     return action;
550 };
551 
552 /** @brief cc.Liquid action */
553 cc.Liquid = cc.Grid3DAction.extend({
554     _waves:null,
555     _amplitude:null,
556     _amplitudeRate:null,
557     getAmplitude:function () {
558         return this._amplitude;
559     },
560     setAmplitude:function (amplitude) {
561         this._amplitude = amplitude;
562     },
563 
564     getAmplitudeRate:function () {
565         return this._amplitudeRate;
566     },
567     setAmplitudeRate:function (amplitudeRate) {
568         this._amplitudeRate = amplitudeRate;
569     },
570 
571     /** initializes the action with amplitude, a grid and duration */
572     initWithWaves:function (wav, amp, gridSize, duration) {
573         if (cc.Grid3DAction.initWithSize(gridSize, duration)) {
574             this._waves = wav;
575             this._amplitude = amp;
576             this._amplitudeRate = 1.0;
577 
578             return true;
579         }
580 
581         return false;
582     },
583     copyWithZone:function (zone) {
584         var newZone = null;
585         var copy = null;
586         if (zone && zone.copyObject) {
587             //in case of being called at sub class
588             copy = zone.copyObject;
589         }
590         else {
591             copy = new cc.Liquid();
592             zone = newZone = new cc.Zone(copy);
593         }
594 
595         cc.Grid3DAction.copyWithZone(zone);
596 
597         copy.initWithWaves(this._waves, this._amplitude, this._gridSize, this.duration);
598 
599         return copy;
600     },
601     update:function (time) {
602         var i, j;
603 
604         for (i = 1; i < this._gridSize.x; ++i) {
605             for (j = 1; j < this._gridSize.y; ++j) {
606                 var v = this.originalVertex(cc.g(i, j));
607                 v.x = (v.x + (Math.sin(time * Math.PI * this._waves * 2 + v.x * .01) * this._amplitude * this._amplitudeRate));
608                 v.y = (v.y + (Math.sin(time * Math.PI * this._waves * 2 + v.y * .01) * this._amplitude * this._amplitudeRate));
609                 this.setVertex(cc.g(i, j), v);
610             }
611         }
612     }
613 });
614 
615 /** creates the action with amplitude, a grid and duration */
616 cc.Liquid.create = function (wav, amp, gridSize, duration) {
617     var action = new cc.Liquid();
618     return action;
619 };
620 
621 /** @brief cc.Waves action */
622 cc.Waves = cc.Grid3DAction.extend({
623     _waves:null,
624     _amplitude:null,
625     _amplitudeRate:null,
626     _vertical:null,
627     _horizontal:null,
628     getAmplitude:function () {
629         return this._amplitude;
630     },
631     setAmplitude:function (amplitude) {
632         this._amplitude = amplitude;
633     },
634 
635     getAmplitudeRate:function () {
636         return this._amplitudeRate;
637     },
638     setAmplitudeRate:function (amplitudeRate) {
639         this._amplitudeRate = amplitudeRate;
640     },
641 
642     /** initializes the action with amplitude, horizontal sin, vertical sin, a grid and duration */
643     initWithWaves:function (wav, amp, h, v, gridSize, duration) {
644         if (cc.Grid3DAction.initWithSize(gridSize, duration)) {
645             this._waves = wav;
646             this._amplitude = amp;
647             this._amplitudeRate = 1.0;
648             this._horizontal = h;
649             this._vertical = v;
650 
651             return true;
652         }
653 
654         return false;
655     },
656     copyWithZone:function (zone) {
657         var newZone = null;
658         var copy = null;
659         if (zone && zone.copyObject) {
660             //in case of being called at sub class
661             copy = zone.copyObject;
662         }
663         else {
664             copy = new cc.Waves();
665             zone = newZone = new cc.Zone(copy);
666         }
667 
668         cc.Grid3DAction.copyWithZone(zone);
669 
670         copy.initWithWaves(this._waves, this._amplitude, this._horizontal, this._vertical, this._gridSize, this.duration);
671 
672         return copy;
673     },
674     update:function (time) {
675         var i, j;
676 
677         for (i = 0; i < this._gridSize.x + 1; ++i) {
678             for (j = 0; j < this._gridSize.y + 1; ++j) {
679                 var v = this.originalVertex(cc.g(i, j));
680 
681                 if (this._vertical) {
682                     v.x = (v.x + (Math.sin(time * Math.PI * this._waves * 2 + v.y * .01) * this._amplitude * this._amplitudeRate));
683                 }
684 
685                 if (this._horizontal) {
686                     v.y = (v.y + (Math.sin(time * Math.PI * this._waves * 2 + v.x * .01) * this._amplitude * this._amplitudeRate));
687                 }
688 
689                 this.setVertex(cc.g(i, j), v);
690             }
691         }
692     }
693 });
694 
695 /** initializes the action with amplitude, horizontal sin, vertical sin, a grid and duration */
696 cc.Waves.create = function (wav, amp, h, v, gridSize, duration) {
697     var action = new cc.Waves();
698     return action;
699 };
700 
701 /** @brief cc.Twirl action */
702 cc.Twirl = cc.Grid3DAction.extend({
703     /* twirl center */
704     _position:null,
705     _twirls:null,
706     _amplitude:null,
707     _amplitudeRate:null,
708     /*@since v0.99.5 */
709     _positionInPixels:null,
710     /** get twirl center */
711     getPosition:function () {
712         return this._position;
713     },
714     /** set twirl center */
715     setPosition:function (position) {
716         this._position = position;
717         this._positionInPixels.x = position.x * cc.CONTENT_SCALE_FACTOR();
718         this._positionInPixels.y = position.y * cc.CONTENT_SCALE_FACTOR();
719     },
720 
721     getAmplitude:function () {
722         return this._amplitude;
723     },
724     setAmplitude:function (amplitude) {
725         this._amplitude = amplitude;
726     },
727 
728     getAmplitudeRate:function () {
729         return this._amplitudeRate;
730     },
731     setAmplitudeRate:function (amplitudeRate) {
732         this._amplitudeRate = amplitudeRate;
733     },
734 
735     /** initializes the action with center position, number of twirls, amplitude, a grid size and duration */
736     initWithPosition:function (pos, t, amp, gridSize, duration) {
737         if (cc.Grid3DAction.initWithSize(gridSize, duration)) {
738             this.setPosition(pos);
739             this._twirls = t;
740             this._amplitude = amp;
741             this._amplitudeRate = 1.0;
742 
743             return true;
744         }
745 
746         return false;
747     },
748     copyWithZone:function (zone) {
749         var newZone = null;
750         var copy = null;
751         if (zone && zone.copyObject) {
752             //in case of being called at sub class
753             copy = zone.copyObject;
754         }
755         else {
756             copy = new cc.Twirl();
757             zone = newZone = new cc.Zone(copy);
758         }
759 
760         cc.Grid3DAction.copyWithZone(zone);
761 
762 
763         copy.initWithPosition(this._position, this._twirls, this._amplitude, this._gridSize, this.duration);
764 
765         return copy;
766     },
767     update:function (time) {
768         var i, j;
769         var c = this._positionInPixels;
770 
771         for (i = 0; i < (this._gridSize.x + 1); ++i) {
772             for (j = 0; j < (this._gridSize.y + 1); ++j) {
773                 var v = this.originalVertex(cc.g(i, j));
774 
775                 var avg = cc.p(i - (this._gridSize.x / 2.0), j - (this._gridSize.y / 2.0));
776                 var r = cc.pLength(avg);
777 
778                 var amp = 0.1 * this._amplitude * this._amplitudeRate;
779                 var a = r * Math.cos(Math.PI / 2.0 + time * Math.PI * this._twirls * 2) * amp;
780 
781                 var d = cc.p(0, 0);
782 
783                 d.x = Math.sin(a) * (v.y - c.y) + Math.cos(a) * (v.x - c.x);
784                 d.y = Math.cos(a) * (v.y - c.y) - Math.sin(a) * (v.x - c.x);
785 
786                 v.x = c.x + d.x;
787                 v.y = c.y + d.y;
788 
789                 this.setVertex(cc.g(i, j), v);
790             }
791         }
792     }
793 });
794 
795 
796 /** creates the action with center position, number of twirls, amplitude, a grid size and duration */
797 cc.Twirl.create = function (pos, t, amp, gridSize, duration) {
798     var action = new cc.Twirl();
799     return action;
800 };
801