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  * Default Node tag
 29  * @constant
 30  * @type Number
 31  */
 32 cc.NODE_TAG_INVALID = -1;
 33 /**
 34  * Node on enter
 35  * @constant
 36  */
 37 cc.NODE_ON_ENTER = null;
 38 /**
 39  * Node on exit
 40  * @constant
 41  */
 42 cc.NODE_ON_EXIT = null;
 43 
 44 /**
 45  *  XXX: Yes, nodes might have a sort problem once every 15 days if the game runs at 60 FPS and each frame sprites are reordered.
 46  * @type Number
 47  */
 48 cc.s_globalOrderOfArrival = 1;
 49 
 50 /** <p>cc.Node is the main element. Anything thats gets drawn or contains things that get drawn is a cc.Node.<br/>
 51  The most popular cc.Nodes are: cc.Scene, cc.Layer, cc.Sprite, cc.Menu.<br/></p>
 52 
 53  <p>The main features of a cc.Node are: <br/>
 54  - They can contain other cc.Node nodes (addChild, getChildByTag, removeChild, etc) <br/>
 55  - They can schedule periodic callback (schedule, unschedule, etc) <br/>
 56  - They can execute actions (runAction, stopAction, etc) <br/></p>
 57 
 58  <p>Some cc.Node nodes provide extra functionality for them or their children.</p>
 59 
 60  <p>Subclassing a cc.Node usually means (one/all) of: <br/>
 61  - overriding init to initialize resources and schedule callbacks  <br/>
 62  - create callbacks to handle the advancement of time <br/>
 63  - overriding draw to render the node   <br/></p>
 64 
 65  <p>Features of cc.Node: <br/>
 66  - position  <br/>
 67  - scale (x, y) <br/>
 68  - rotation (in degrees, clockwise) <br/>
 69  - anchor point<br/>
 70  - size <br/>
 71  - visible<br/>
 72  - z-order <br/>
 73  - openGL z position <br/></P>
 74 
 75  <p> Default values: <br/>
 76  - rotation: 0 <br/>
 77  - position: (x=0,y=0) <br/>
 78  - scale: (x=1,y=1) <br/>
 79  - contentSize: (x=0,y=0)<br/>
 80  - anchorPoint: (x=0,y=0)<br/></p>
 81 
 82  <p> Limitations:<br/>
 83  - A cc.Node is a "void" object. It doesn't have a texture <br/></P>
 84 
 85  <p>Order in transformations with grid disabled <br/>
 86  -# The node will be translated (position)  <br/>
 87  -# The node will be rotated (rotation)<br/>
 88  -# The node will be scaled (scale)  <br/>
 89 
 90  <p>Order in transformations with grid enabled<br/>
 91  -# The node will be translated (position)<br/>
 92  -# The node will be rotated (rotation) <br/>
 93  -# The node will be scaled (scale) <br/>
 94  -# The grid will capture the screen <br/>
 95  -# The node will be moved according to the camera values (camera) <br/>
 96  -# The grid will render the captured screen <br/></P>
 97  * @class
 98  * @extends cc.Class
 99  * @example
100  * // example
101  * cc.Sprite = cc.Node.extend({});
102  * cc.Sprite.initWithImage = function(){
103  * };
104  */
105 cc.Node = cc.Class.extend(/** @lends cc.Node# */{
106     _zOrder:0,
107     _vertexZ:0.0,
108 
109     _rotationX:0,
110     _rotationY:0.0,
111     _scaleX:1.0,
112     _scaleY:1.0,
113     _position:null,
114     _skewX:0.0,
115     _skewY:0.0,
116     // children (lazy allocs),
117     _children:null,
118     // lazy alloc,
119     _visible:true,
120     _anchorPoint:null,
121     _anchorPointInPoints:null,
122     _contentSize:null,
123     _running:false,
124     _parent:null,
125     // "whole screen" objects. like Scenes and Layers, should set _ignoreAnchorPointForPosition to true
126     _ignoreAnchorPointForPosition:false,
127     _tag:cc.NODE_TAG_INVALID,
128     // userData is always inited as nil
129     _userData:null,
130     _userObject:null,
131     _transformDirty:true,
132     _inverseDirty:true,
133     _cacheDirty:true,
134     _transformGLDirty:null,
135     _transform:null,
136     _inverse:null,
137 
138     //since 2.0 api
139     _reorderChildDirty:false,
140     _shaderProgram:null,
141     _orderOfArrival:0,
142 
143     _actionManager:null,
144     _scheduler:null,
145 
146     _initializedNode:false,
147     _additionalTransformDirty:false,
148     _additionalTransform:null,
149     _componentContainer:null,
150     _isTransitionFinished:false,
151 
152     _rotationRadiansX:0,
153     _rotationRadiansY:0,
154 
155     _initNode:function () {
156         this._anchorPoint = cc.p(0, 0);
157         this._anchorPointInPoints = cc.p(0, 0);
158         this._contentSize = cc.size(0, 0);
159         this._position = cc.p(0, 0);
160         this._children = [];
161         this._transform = {a:1, b:0, c:0, d:1, tx:0, ty:0};
162 
163         var director = cc.Director.getInstance();
164         this._actionManager = director.getActionManager();
165         this._scheduler = director.getScheduler();
166         this._initializedNode = true;
167         this._additionalTransform = cc.AffineTransformMakeIdentity();
168         if(cc.ComponentContainer){
169             this._componentContainer = new cc.ComponentContainer(this);
170         }
171     },
172 
173     /**
174      * Initializes the instance of cc.Node
175      * @returns {boolean} Whether the initialization was successful.
176      */
177     init:function () {
178         if (this._initializedNode === false)
179             this._initNode();
180         return true;
181     },
182 
183     /**
184      * @param {Array} array
185      * @param {cc.Node.StateCallbackType} callbackType
186      * @private
187      */
188     _arrayMakeObjectsPerformSelector:function (array, callbackType) {
189         if (!array || array.length === 0)
190             return;
191 
192         var i, len = array.length,node;
193         var nodeCallbackType = cc.Node.StateCallbackType;
194         switch (callbackType) {
195             case nodeCallbackType.onEnter:
196                 for (i = 0; i < len; i++) {
197                     node = array[i];
198                     if (node)
199                         node.onEnter();
200                 }
201                 break;
202             case nodeCallbackType.onExit:
203                 for (i = 0; i < len; i++) {
204                     node = array[i];
205                     if (node)
206                         node.onExit();
207                 }
208                 break;
209             case nodeCallbackType.onEnterTransitionDidFinish:
210                 for (i = 0; i < len; i++) {
211                     node = array[i];
212                     if (node)
213                         node.onEnterTransitionDidFinish();
214                 }
215                 break;
216             case nodeCallbackType.cleanup:
217                 for (i = 0; i < len; i++) {
218                     node = array[i];
219                     if (node)
220                         node.cleanup();
221                 }
222                 break;
223             case nodeCallbackType.updateTransform:
224                 for (i = 0; i < len; i++) {
225                     node = array[i];
226                     if (node)
227                         node.updateTransform();
228                 }
229                 break;
230             case nodeCallbackType.onExitTransitionDidStart:
231                 for (i = 0; i < len; i++) {
232                     node = array[i];
233                     if (node)
234                         node.onExitTransitionDidStart();
235                 }
236                 break;
237             case nodeCallbackType.sortAllChildren:
238                 for (i = 0; i < len; i++) {
239                     node = array[i];
240                     if (node)
241                         node.sortAllChildren();
242                 }
243                 break;
244             default :
245                 throw "Unknown callback function";
246                 break;
247         }
248     },
249 
250     /**
251      * set the dirty node
252      */
253     setNodeDirty:null,
254 
255     _setNodeDirtyForCanvas:function () {
256         this._setNodeDirtyForCache();
257         if(this._transformDirty === false)
258             this._transformDirty = this._inverseDirty = true;
259     },
260 
261     _setNodeDirtyForWebGL:function () {
262         if(this._transformDirty === false)
263             this._transformDirty = this._inverseDirty = true;
264     },
265 
266     /**
267      *  <p>get the skew degrees in X </br>
268      *  The X skew angle of the node in degrees.  <br/>
269      *  This angle describes the shear distortion in the X direction.<br/>
270      *  Thus, it is the angle between the Y axis and the left edge of the shape </br>
271      *  The default skewX angle is 0. Positive values distort the node in a CW direction.</br>
272      *  </p>
273      * @return {Number} The X skew angle of the node in degrees.
274      */
275     getSkewX:function () {
276         return this._skewX;
277     },
278 
279     /**
280      * <p>
281      *     Changes the X skew angle of the node in degrees.                                                    <br/>
282      *                                                                                                         <br/>
283      *      This angle describes the shear distortion in the X direction.                                      <br/>
284      *      Thus, it is the angle between the Y axis and the left edge of the shape                            <br/>
285      *      The default skewX angle is 0. Positive values distort the node in a CW direction.
286      * </p>
287      * @param {Number} newSkewX The X skew angle of the node in degrees.
288      */
289     setSkewX:function (newSkewX) {
290         this._skewX = newSkewX;
291         this.setNodeDirty();
292     },
293 
294     /**
295      * <p>get the skew degrees in Y               <br/>
296      * The Y skew angle of the node in degrees.                            <br/>
297      * This angle describes the shear distortion in the Y direction.       <br/>
298      * Thus, it is the angle between the X axis and the bottom edge of the shape       <br/>
299      * The default skewY angle is 0. Positive values distort the node in a CCW direction.    <br/>
300      * </p>
301      * @return {Number} The Y skew angle of the node in degrees.
302      */
303     getSkewY:function () {
304         return this._skewY;
305     },
306 
307     /**
308      * <p>
309      * Changes the Y skew angle of the node in degrees.
310      *
311      * This angle describes the shear distortion in the Y direction.
312      * Thus, it is the angle between the X axis and the bottom edge of the shape
313      * The default skewY angle is 0. Positive values distort the node in a CCW direction.
314      * </p>
315      * @param {Number} newSkewY  The Y skew angle of the node in degrees.
316      */
317     setSkewY:function (newSkewY) {
318         this._skewY = newSkewY;
319         this.setNodeDirty();
320     },
321 
322     /**
323      * zOrder getter
324      * @return {Number}
325      */
326     getZOrder:function () {
327         return this._zOrder;
328     },
329 
330     /**
331      * <p>
332      *     Sets the z order which stands for the drawing order                                                     <br/>
333      *                                                                                                             <br/>
334      *     This is an internal method. Don't call it outside the framework.                                        <br/>
335      *     The difference between setZOrder(int) and _setOrder(int) is:                                            <br/>
336      *        - _setZOrder(int) is a pure setter for m_nZOrder member variable                                    <br/>
337      *        - setZOrder(int) firstly changes m_nZOrder, then recorder this node in its parent's children array.
338      * </p>
339      * @param {Number} z
340      * @private
341      */
342     _setZOrder:function (z) {
343         this._zOrder = z;
344     },
345 
346     /**
347      * <p>
348      *     Sets the Z order which stands for the drawing order, and reorder this node in its parent's children array.     <br/>
349      *                                                                                                                    <br/>
350      *      The Z order of node is relative to its "brothers": children of the same parent.                               <br/>
351      *      It's nothing to do with OpenGL's z vertex. This one only affects the draw order of nodes in cocos2d.          <br/>
352      *      The larger number it is, the later this node will be drawn in each message loop.                              <br/>
353      *      Please refer to setVertexZ(float) for the difference.
354      * </p>
355      * @param {Number} z Z order of this node.
356      */
357     setZOrder:function (z) {
358         // ZOrder is set on parent's reorderChild.
359         if (this._parent)
360             this._parent.reorderChild(this, z);
361         else
362             this._setZOrder(z);
363     },
364 
365     /**
366      * Gets WebGL Z vertex of this node.
367      * @return {Number} WebGL Z vertex of this node
368      */
369     getVertexZ:function () {
370         return this._vertexZ;
371     },
372 
373     /**
374      * <p>
375      *     Sets the real WebGL Z vertex.                                                                          <br/>
376      *                                                                                                            <br/>
377      *      Differences between openGL Z vertex and cocos2d Z order:                                              <br/>
378      *      - OpenGL Z modifies the Z vertex, and not the Z order in the relation between parent-children         <br/>
379      *      - OpenGL Z might require to set 2D projection                                                         <br/>
380      *      - cocos2d Z order works OK if all the nodes uses the same openGL Z vertex. eg: vertexZ = 0            <br/>
381      *                                                                                                            <br/>
382      *      @warning Use it at your own risk since it might break the cocos2d parent-children z order
383      * </p>
384      * @param {Number} Var
385      */
386     setVertexZ:function (Var) {
387         this._vertexZ = Var;
388     },
389 
390     /**
391      * The rotation (angle) of the node in degrees. 0 is the default rotation angle. Positive values rotate node CW.
392      * @return {Number} The rotation of the node in degrees.
393      */
394     getRotation:function () {
395         if(this._rotationX !== this._rotationY)
396             cc.log("cc.Node.rotation(): RotationX != RotationY. Don't know which one to return");
397         return this._rotationX;
398     },
399 
400     /**
401      * <p>
402      *     Sets the rotation (angle) of the node in degrees.                                             <br/>
403      *                                                                                                   <br/>
404      *      0 is the default rotation angle.                                                             <br/>
405      *      Positive values rotate node clockwise, and negative values for anti-clockwise.
406      * </p>
407      * @param {Number} newRotation The rotation of the node in degrees.
408      */
409     setRotation:function (newRotation) {
410         this._rotationX = this._rotationY = newRotation;
411         this._rotationRadiansX = this._rotationX * 0.017453292519943295; //(Math.PI / 180);
412         this._rotationRadiansY = this._rotationY * 0.017453292519943295; //(Math.PI / 180);
413         this.setNodeDirty();
414     },
415 
416     /**
417      * The rotation (angle) of the node in degrees. 0 is the default rotation angle. <br/>
418      * Positive values rotate node CW. It only modifies the X rotation performing a horizontal rotational skew .
419      * (support only in WebGl rendering mode)
420      * @return {Number} The X rotation in degrees.
421      */
422     getRotationX:function () {
423         return this._rotationX;
424     },
425 
426     /**
427      * <p>
428      *     Sets the X rotation (angle) of the node in degrees which performs a horizontal rotational skew.        <br/>
429      *                                                                                                            <br/>
430      *     0 is the default rotation angle.                                                                       <br/>
431      *     Positive values rotate node clockwise, and negative values for anti-clockwise.
432      * </p>
433      * @param {Number} rotationX The X rotation in degrees which performs a horizontal rotational skew.
434      */
435     setRotationX:function (rotationX) {
436         this._rotationX = rotationX;
437         this._rotationRadiansX = this._rotationX * 0.017453292519943295; //(Math.PI / 180);
438         this.setNodeDirty();
439     },
440 
441     /**
442      * The rotation (angle) of the node in degrees. 0 is the default rotation angle.  <br/>
443      * Positive values rotate node CW. It only modifies the Y rotation performing a vertical rotational skew .
444      * @return {Number} The Y rotation in degrees.
445      */
446     getRotationY:function () {
447         return this._rotationY;
448     },
449 
450     /**
451      * <p>
452      *    Sets the Y rotation (angle) of the node in degrees which performs a vertical rotational skew.         <br/>
453      *                                                                                                          <br/>
454      *      0 is the default rotation angle.                                                                    <br/>
455      *      Positive values rotate node clockwise, and negative values for anti-clockwise.
456      * </p>
457      * @param rotationY The Y rotation in degrees.
458      */
459     setRotationY:function (rotationY) {
460         this._rotationY = rotationY;
461         this._rotationRadiansY = this._rotationY * 0.017453292519943295;  //(Math.PI / 180);
462         this.setNodeDirty();
463     },
464 
465     /** Get the scale factor of the node.
466      * @warning: Assert when _scaleX != _scaleY.
467      * @return {Number}
468      */
469     getScale:function () {
470         if(this._scaleX !== this._scaleY)
471             cc.log("cc.Node.getScale(): ScaleX != ScaleY. Don't know which one to return");
472         return this._scaleX;
473     },
474 
475     /**
476      * The scale factor of the node. 1.0 is the default scale factor. It modifies the X and Y scale at the same time.
477      * @param {Number} scale or scaleX value
478      * @param {Number} [scaleY=]
479      */
480     setScale:function (scale, scaleY) {
481         this._scaleX = scale;
482         this._scaleY = (scaleY || scaleY === 0) ? scaleY : scale;
483         this.setNodeDirty();
484     },
485 
486     /**
487      * Returns the scale factor on X axis of this node
488      * @return {Number} The scale factor on X axis.
489      */
490     getScaleX:function () {
491         return this._scaleX;
492     },
493 
494     /**
495      * <p>
496      *     Changes the scale factor on X axis of this node                                   <br/>
497      *     The deafult value is 1.0 if you haven't changed it before
498      * </p>
499      * @param {Number} newScaleX The scale factor on X axis.
500      */
501     setScaleX:function (newScaleX) {
502         this._scaleX = newScaleX;
503         this.setNodeDirty();
504     },
505 
506     /**
507      * Returns the scale factor on Y axis of this node
508      * @return {Number} The scale factor on Y axis.
509      */
510     getScaleY:function () {
511         return this._scaleY;
512     },
513 
514     /**
515      * <p>
516      *     Changes the scale factor on Y axis of this node                                            <br/>
517      *     The Default value is 1.0 if you haven't changed it before.
518      * </p>
519      * @param {Number} newScaleY The scale factor on Y axis.
520      */
521     setScaleY:function (newScaleY) {
522         this._scaleY = newScaleY;
523         this.setNodeDirty();
524     },
525 
526     /**
527      * <p>
528      *     Changes the position (x,y) of the node in OpenGL coordinates
529      *     Usually we use ccp(x,y) to compose CCPoint object.
530      *     The original point (0,0) is at the left-bottom corner of screen.
531      *     and Passing two numbers (x,y) is much efficient than passing CCPoint object.
532      * </p>
533      * @param {cc.Point|Number} newPosOrxValue The position (x,y) of the node in coordinates or  X coordinate for position
534      * @param {Number} [yValue] Y coordinate for position
535      * @example
536      *    var size = cc.Director.getInstance().getWinSize();
537      *    node.setPosition(size.width/2, size.height/2);
538      */
539     setPosition:function (newPosOrxValue, yValue) {
540         var locPosition = this._position;
541         if (yValue === undefined) {
542             locPosition.x = newPosOrxValue.x;
543             locPosition.y = newPosOrxValue.y;
544         } else {
545 	        locPosition.x = newPosOrxValue;
546 	        locPosition.y = yValue;
547         }
548         this.setNodeDirty();
549     },
550 
551     /**
552      * <p>Position (x,y) of the node in OpenGL coordinates. (0,0) is the left-bottom corner. </p>
553      * @const
554      * @return {cc.Point} The position (x,y) of the node in OpenGL coordinates
555      */
556     getPosition:function () {
557         return cc.p(this._position);
558     },
559 
560     /**
561      * @return {Number}
562      */
563     getPositionX:function () {
564         return this._position.x;
565     },
566 
567     /**
568      * @param {Number} x
569      */
570     setPositionX:function (x) {
571         this._position.x = x;
572         this.setNodeDirty();
573     },
574 
575     /**
576      * @return {Number}
577      */
578     getPositionY:function () {
579         return  this._position.y;
580     },
581 
582     /**
583      * @param {Number} y
584      */
585     setPositionY:function (y) {
586         this._position.y = y;
587         this.setNodeDirty();
588     },
589 
590     /**
591      * Get the amount of children.
592      * @return {Number} The amount of children.
593      */
594     getChildrenCount:function () {
595         return this._children.length;
596     },
597 
598     /**
599      * Return an array of children  <br/>
600      * Composing a "tree" structure is a very important feature of CCNode
601      * @return {Array} An array of children
602      * @example
603      *  //This sample code traverses all children nodes, and set their position to (0,0)
604      *  var allChildren = parent.getChildren();
605      * for(var i = 0; i< allChildren.length; i++) {
606      *     allChildren[i].setPosition(0,0);
607      * }
608      */
609     getChildren:function () {
610         return this._children;
611     },
612 
613     /**
614      * Determines if the node is visible
615      * @see setVisible(bool)
616      * @return {Boolean} true if the node is visible, false if the node is hidden.
617      */
618     isVisible:function () {
619         return this._visible;
620     },
621 
622     /**
623      * Sets whether the node is visible <br/>
624      * The default value is true, a node is default to visible
625      * @param {Boolean} Var true if the node is visible, false if the node is hidden.
626      */
627     setVisible:function (Var) {
628         this._visible = Var;
629         this.setNodeDirty();
630     },
631 
632     /**
633      *  <p>anchorPoint is the point around which all transformations and positioning manipulations take place.<br/>
634      *  It's like a pin in the node where it is "attached" to its parent. <br/>
635      *  The anchorPoint is normalized, like a percentage. (0,0) means the bottom-left corner and (1,1) means the top-right corner. <br/>
636      *  But you can use values higher than (1,1) and lower than (0,0) too.  <br/>
637      *  The default anchorPoint is (0.5,0.5), so it starts in the center of the node. <br/></p>
638      *  @const
639      * @return {cc.Point}  The anchor point of node.
640      */
641     getAnchorPoint:function () {
642         return cc.p(this._anchorPoint);
643     },
644 
645     /**
646      * <p>
647      *     Sets the anchor point in percent.                                                                                              <br/>
648      *                                                                                                                                    <br/>
649      *     anchorPoint is the point around which all transformations and positioning manipulations take place.                            <br/>
650      *     It's like a pin in the node where it is "attached" to its parent.                                                              <br/>
651      *     The anchorPoint is normalized, like a percentage. (0,0) means the bottom-left corner and (1,1) means the top-right corner.     <br/>
652      *     But you can use values higher than (1,1) and lower than (0,0) too.                                                             <br/>
653      *     The default anchorPoint is (0.5,0.5), so it starts in the center of the node.
654      * </p>
655      * @param {cc.Point|Number} point The anchor point of node or The anchor point.x of node.
656      * @param {Number} [y] The anchor point.y of node.
657      */
658     setAnchorPoint:function (point, y) {
659         var locAnchorPoint = this._anchorPoint;
660         if (y === undefined) {
661 	        if ((point.x === locAnchorPoint.x) && (point.y === locAnchorPoint.y))
662 		        return;
663 	        locAnchorPoint.x = point.x;
664 	        locAnchorPoint.y = point.y;
665         } else {
666 	        if ((point === locAnchorPoint.x) && (y === locAnchorPoint.y))
667 		        return;
668 	        locAnchorPoint.x = point;
669 	        locAnchorPoint.y = y;
670         }
671         var locAPP = this._anchorPointInPoints, locSize = this._contentSize;
672         locAPP.x = locSize.width * locAnchorPoint.x;
673         locAPP.y = locSize.height * locAnchorPoint.y;
674         this.setNodeDirty();
675     },
676 
677     /**
678      *  The anchorPoint in absolute pixels.  <br/>
679      *  you can only read it. If you wish to modify it, use anchorPoint instead
680      *  @see getAnchorPoint()
681      *  @const
682      * @return {cc.Point} The anchor point in absolute pixels.
683      */
684     getAnchorPointInPoints:function () {
685         return cc.p(this._anchorPointInPoints);
686     },
687 
688     /**
689      * <p>The untransformed size of the node. <br/>
690      * The contentSize remains the same no matter the node is scaled or rotated.<br/>
691      * All nodes has a size. Layer and Scene has the same size of the screen. <br/></p>
692      * @const
693      * @return {cc.Size} The untransformed size of the node.
694      */
695     getContentSize:function () {
696         return cc.size(this._contentSize);
697     },
698 
699     /**
700      * <p>
701      *     Sets the untransformed size of the node.                                             <br/>
702      *                                                                                          <br/>
703      *     The contentSize remains the same no matter the node is scaled or rotated.            <br/>
704      *     All nodes has a size. Layer and Scene has the same size of the screen.
705      * </p>
706      * @param {cc.Size|Number} size The untransformed size of the node or The untransformed size's width of the node.
707      * @param {Number} [height] The untransformed size's height of the node.
708      */
709     setContentSize:function (size, height) {
710         var locContentSize = this._contentSize;
711         if (height === undefined) {
712 	        if ((size.width === locContentSize.width) && (size.height === locContentSize.height))
713 		        return;
714 	        locContentSize.width = size.width;
715 	        locContentSize.height = size.height;
716         } else {
717 	        if ((size === locContentSize.width) && (height === locContentSize.height))
718 		        return;
719 	        locContentSize.width = size;
720 	        locContentSize.height = height;
721         }
722         var locAPP = this._anchorPointInPoints, locAnchorPoint = this._anchorPoint;
723         locAPP.x = locContentSize.width * locAnchorPoint.x;
724         locAPP.y = locContentSize.height * locAnchorPoint.y;
725         this.setNodeDirty();
726     },
727 
728     /**
729      * <p>
730      *     Returns whether or not the node accepts event callbacks.                                     <br/>
731      *     Running means the node accept event callbacks like onEnter(), onExit(), update()
732      * </p>
733      * @return {Boolean} Whether or not the node is running.
734      */
735     isRunning:function () {
736         return this._running;
737     },
738 
739     /**
740      * Returns a pointer to the parent node
741      * @return {cc.Node} A pointer to the parent node
742      */
743     getParent:function () {
744         return this._parent;
745     },
746 
747     /**
748      * Sets the parent node
749      * @param {cc.Node} Var A pointer to the parent node
750      */
751     setParent:function (Var) {
752         this._parent = Var;
753     },
754 
755     /**
756      * Gets whether the anchor point will be (0,0) when you position this node.
757      * @see ignoreAnchorPointForPosition(bool)
758      * @return {Boolean} true if the anchor point will be (0,0) when you position this node.
759      */
760     isIgnoreAnchorPointForPosition:function () {
761         return this._ignoreAnchorPointForPosition;
762     },
763 
764     /**
765      * <p>
766      *     Sets whether the anchor point will be (0,0) when you position this node.                              <br/>
767      *                                                                                                           <br/>
768      *     This is an internal method, only used by CCLayer and CCScene. Don't call it outside framework.        <br/>
769      *     The default value is false, while in CCLayer and CCScene are true
770      * </p>
771      * @param {Boolean} newValue true if anchor point will be (0,0) when you position this node
772      */
773     ignoreAnchorPointForPosition:function (newValue) {
774         if (newValue != this._ignoreAnchorPointForPosition) {
775             this._ignoreAnchorPointForPosition = newValue;
776             this.setNodeDirty();
777         }
778     },
779 
780     /**
781      * Returns a tag that is used to identify the node easily.
782      *
783      * @return {Number} An integer that identifies the node.
784      * @example
785      *  //You can set tags to node then identify them easily.
786      * // set tags
787      * node1.setTag(TAG_PLAYER);
788      * node2.setTag(TAG_MONSTER);
789      * node3.setTag(TAG_BOSS);
790      * parent.addChild(node1);
791      * parent.addChild(node2);
792      * parent.addChild(node3);
793      * // identify by tags
794      * var allChildren = parent.getChildren();
795      * for(var i = 0; i < allChildren.length; i++){
796      *     switch(node.getTag()) {
797      *         case TAG_PLAYER:
798      *             break;
799      *         case TAG_MONSTER:
800      *             break;
801      *         case TAG_BOSS:
802      *             break;
803      *     }
804      * }
805      */
806     getTag:function () {
807         return this._tag;
808     },
809 
810     /**
811      * Changes the tag that is used to identify the node easily. <br/>
812      * Please refer to getTag for the sample code.
813      * @param {Number} Var A integer that identifies the node.
814      */
815     setTag:function (Var) {
816         this._tag = Var;
817     },
818 
819     /**
820      * <p>
821      *     Returns a custom user data pointer                                                               <br/>
822      *     You can set everything in UserData pointer, a data block, a structure or an object.
823      * </p>
824      * @return {object}  A custom user data pointer
825      */
826     getUserData:function () {
827         return this._userData;
828     },
829 
830     /**
831      * <p>
832      *    Sets a custom user data pointer                                                                   <br/>
833      *    You can set everything in UserData pointer, a data block, a structure or an object, etc.
834      * </p>
835      * @warning Don't forget to release the memory manually,especially before you change this data pointer, and before this node is autoreleased.
836      * @param {object} Var A custom user data
837      */
838     setUserData:function (Var) {
839         this._userData = Var;
840     },
841 
842     /**
843      * Returns a user assigned CCObject.                             <br/>
844      * Similar to userData, but instead of holding a void* it holds an id
845      * @return {object} A user assigned CCObject
846      */
847     getUserObject:function () {
848         return this._userObject;
849     },
850 
851     /**
852      * <p>
853      *      Returns a user assigned CCObject                                                                                       <br/>
854      *      Similar to UserData, but instead of holding a void* it holds an object.                                               <br/>
855      *      The UserObject will be retained once in this method, and the previous UserObject (if existed) will be release.         <br/>
856      *      The UserObject will be released in CCNode's destruction.
857      * </p>
858      * @param {object} newValue A user assigned CCObject
859      */
860     setUserObject:function (newValue) {
861         if (this._userObject != newValue) {
862             this._userObject = newValue;
863         }
864     },
865 
866 
867     /**
868      * Returns the arrival order, indicates which children is added previously.
869      * @return {Number} The arrival order.
870      */
871     getOrderOfArrival:function () {
872         return this._orderOfArrival;
873     },
874 
875     /**
876      * <p>
877      *     Sets the arrival order when this node has a same ZOrder with other children.                             <br/>
878      *                                                                                                              <br/>
879      *     A node which called addChild subsequently will take a larger arrival order,                              <br/>
880      *     If two children have the same Z order, the child with larger arrival order will be drawn later.
881      * </p>
882      * @warning This method is used internally for zOrder sorting, don't change this manually
883      * @param {Number} Var  The arrival order.
884      */
885     setOrderOfArrival:function (Var) {
886         this._orderOfArrival = Var;
887     },
888 
889     /**
890      * <p>Gets the CCActionManager object that is used by all actions.<br/>
891      * (IMPORTANT: If you set a new cc.ActionManager, then previously created actions are going to be removed.)</p>
892      * @see setActionManager()
893      * @return {cc.ActionManager} A CCActionManager object.
894      */
895     getActionManager:function () {
896         if (!this._actionManager) {
897             this._actionManager = cc.Director.getInstance().getActionManager();
898         }
899         return this._actionManager;
900     },
901 
902     /**
903      * <p>Sets the cc.ActionManager object that is used by all actions. </p>
904      * @warning If you set a new CCActionManager, then previously created actions will be removed.
905      * @param {cc.ActionManager} actionManager A CCActionManager object that is used by all actions.
906      */
907     setActionManager:function (actionManager) {
908         if (this._actionManager != actionManager) {
909             this.stopAllActions();
910             this._actionManager = actionManager;
911         }
912     },
913 
914     /**
915      * <p>
916      *   cc.Scheduler used to schedule all "updates" and timers.<br/>
917      *   IMPORTANT: If you set a new cc.Scheduler, then previously created timers/update are going to be removed.
918      * </p>
919      * @return {cc.Scheduler} A CCScheduler object.
920      */
921     getScheduler:function () {
922         if (!this._scheduler) {
923             this._scheduler = cc.Director.getInstance().getScheduler();
924         }
925         return this._scheduler;
926     },
927 
928     /**
929      * <p>
930      *   Sets a CCScheduler object that is used to schedule all "updates" and timers.           <br/>
931      * </p>
932      * @warning If you set a new CCScheduler, then previously created timers/update are going to be removed.
933      * @param scheduler A cc.Scheduler object that is used to schedule all "update" and timers.
934      */
935     setScheduler:function (scheduler) {
936         if (this._scheduler != scheduler) {
937             this.unscheduleAllCallbacks();
938             this._scheduler = scheduler;
939         }
940     },
941 
942     /**
943      * Returns a "local" axis aligned bounding box of the node. <br/>
944      * The returned box is relative only to its parent.
945      * @note This method returns a temporary variable, so it can't returns const CCRect&
946      * @const
947      * @return {cc.Rect}
948      */
949     getBoundingBox:function () {
950         var rect = cc.rect(0, 0, this._contentSize.width, this._contentSize.height);
951         return cc._RectApplyAffineTransformIn(rect, this.nodeToParentTransform());
952     },
953 
954     /**
955      * Stops all running actions and schedulers
956      */
957     cleanup:function () {
958         // actions
959         this.stopAllActions();
960         this.unscheduleAllCallbacks();
961 
962         // timers
963         this._arrayMakeObjectsPerformSelector(this._children, cc.Node.StateCallbackType.cleanup);
964     },
965 
966     /**
967      * Gets the description string. It makes debugging easier.
968      * @return {String}
969      */
970     description:function () {
971         return "<cc.Node | Tag =" + this._tag + ">";
972     },
973 
974     // composition: GET
975     /**
976      * Gets a child from the container given its tag
977      * @param {Number} aTag An identifier to find the child node.
978      * @return {cc.Node} a CCNode object whose tag equals to the input parameter
979      */
980     getChildByTag:function (aTag) {
981         var __children = this._children;
982         if (__children != null) {
983             for (var i = 0; i < __children.length; i++) {
984                 var node = __children[i];
985                 if (node && node._tag == aTag)
986                     return node;
987             }
988         }
989         //throw "not found";
990         return null;
991     },
992     // composition: ADD
993 
994     /** <p>"add" logic MUST only be on this method <br/> </p>
995      *
996      * <p>If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.</p>
997      *
998      * @param {cc.Node} child  A child node
999      * @param {Number} [zOrder=]  Z order for drawing priority. Please refer to setZOrder(int)
1000      * @param {Number} [tag=]  A integer to identify the node easily. Please refer to setTag(int)
1001      */
1002     addChild:function (child, zOrder, tag) {
1003         if(!child)
1004             throw "cc.Node.addChild(): child must be non-null";
1005         if (child === this) {
1006             cc.log('cc.Node.addChild(): An Node can\'t be added as a child of itself.');
1007             return;
1008         }
1009 
1010         if (child._parent !== null) {
1011             cc.log("cc.Node.addChild(): child already added. It can't be added again");
1012             return;
1013         }
1014 
1015         var tmpzOrder = (zOrder != null) ? zOrder : child._zOrder;
1016         child._tag = (tag != null) ? tag : child._tag;
1017         this._insertChild(child, tmpzOrder);
1018         child._parent = this;
1019 
1020         if (this._running) {
1021             child.onEnter();
1022             // prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter
1023             if(this._isTransitionFinished)
1024                 child.onEnterTransitionDidFinish();
1025         }
1026     },
1027 
1028     // composition: REMOVE
1029     /**
1030      * Remove itself from its parent node. If cleanup is true, then also remove all actions and callbacks. <br/>
1031      * If the cleanup parameter is not passed, it will force a cleanup. <br/>
1032      * If the node orphan, then nothing happens.
1033      * @param {Boolean} cleanup true if all actions and callbacks on this node should be removed, false otherwise.
1034      * @see removeFromParentAndCleanup(bool)
1035      */
1036     removeFromParent:function (cleanup) {
1037         if (this._parent) {
1038             if (cleanup == null)
1039                 cleanup = true;
1040             this._parent.removeChild(this, cleanup);
1041         }
1042     },
1043 
1044     /**
1045      * Removes this node itself from its parent node.  <br/>
1046      * If the node orphan, then nothing happens.
1047      * @deprecated
1048      * @param {Boolean} cleanup true if all actions and callbacks on this node should be removed, false otherwise.
1049      */
1050     removeFromParentAndCleanup:function (cleanup) {
1051         cc.log("removeFromParentAndCleanup is deprecated. Use removeFromParent instead");
1052         this.removeFromParent(cleanup);
1053     },
1054 
1055     /** <p>Removes a child from the container. It will also cleanup all running actions depending on the cleanup parameter. </p>
1056      * If the cleanup parameter is not passed, it will force a cleanup. <br/>
1057      *<p> "remove" logic MUST only be on this method  <br/>
1058      * If a class wants to extend the 'removeChild' behavior it only needs <br/>
1059      * to override this method </p>
1060      *
1061      * @param {cc.Node} child  The child node which will be removed.
1062      * @param {Boolean|null} [cleanup=null]  true if all running actions and callbacks on the child node will be cleanup, false otherwise.
1063      */
1064     removeChild:function (child, cleanup) {
1065         // explicit nil handling
1066         if (this._children.length === 0)
1067             return;
1068 
1069         if (cleanup == null)
1070             cleanup = true;
1071         if (this._children.indexOf(child) > -1)
1072             this._detachChild(child, cleanup);
1073 
1074         this.setNodeDirty();
1075     },
1076 
1077     /**
1078      * Removes a child from the container by tag value. It will also cleanup all running actions depending on the cleanup parameter.
1079      * If the cleanup parameter is not passed, it will force a cleanup. <br/>
1080      * @param {Number} tag An integer number that identifies a child node
1081      * @param {Boolean} cleanup true if all running actions and callbacks on the child node will be cleanup, false otherwise.
1082      * @see removeChildByTag(int, bool)
1083      */
1084     removeChildByTag:function (tag, cleanup) {
1085         if(tag === cc.NODE_TAG_INVALID)
1086             cc.log("cc.Node.removeChildByTag(): argument tag is an invalid tag");
1087 
1088         var child = this.getChildByTag(tag);
1089         if (child == null)
1090             cc.log("cocos2d: removeChildByTag(tag = " + tag + "): child not found!");
1091         else
1092             this.removeChild(child, cleanup);
1093     },
1094 
1095     /**
1096      * Removes all children from the container and do a cleanup all running actions depending on the cleanup parameter.
1097      * @deprecated
1098      * @param {Boolean | null } cleanup
1099      */
1100     removeAllChildrenWithCleanup:function (cleanup) {
1101         cc.log("removeAllChildrenWithCleanup is deprecated. Use removeAllChildren instead");
1102         this.removeAllChildren(cleanup);
1103     },
1104 
1105     /**
1106      * Removes all children from the container and do a cleanup all running actions depending on the cleanup parameter. <br/>
1107      * If the cleanup parameter is not passed, it will force a cleanup. <br/>
1108      * @param {Boolean | null } cleanup true if all running actions on all children nodes should be cleanup, false otherwise.
1109      */
1110     removeAllChildren:function (cleanup) {
1111         // not using detachChild improves speed here
1112         var __children = this._children;
1113         if (__children != null) {
1114             if (cleanup == null)
1115                 cleanup = true;
1116             for (var i = 0; i < __children.length; i++) {
1117                 var node = __children[i];
1118                 if (node) {
1119                     // IMPORTANT:
1120                     //  -1st do onExit
1121                     //  -2nd cleanup
1122                     if (this._running) {
1123                         node.onExitTransitionDidStart();
1124                         node.onExit();
1125                     }
1126                     if (cleanup)
1127                         node.cleanup();
1128                     // set parent nil at the end
1129                     node.setParent(null);
1130                 }
1131             }
1132             this._children.length = 0;
1133         }
1134     },
1135 
1136     /**
1137      * @param {cc.Node} child
1138      * @param {Boolean} doCleanup
1139      * @private
1140      */
1141     _detachChild:function (child, doCleanup) {
1142         // IMPORTANT:
1143         //  -1st do onExit
1144         //  -2nd cleanup
1145         if (this._running) {
1146             child.onExitTransitionDidStart();
1147             child.onExit();
1148         }
1149 
1150         // If you don't do cleanup, the child's actions will not get removed and the
1151         // its scheduledSelectors_ dict will not get released!
1152         if (doCleanup)
1153             child.cleanup();
1154 
1155         // set parent nil at the end
1156         child.setParent(null);
1157 
1158         cc.ArrayRemoveObject(this._children, child);
1159     },
1160 
1161     /** helper used by reorderChild & add
1162      * @param {cc.Node} child
1163      * @param {Number} z
1164      * @private
1165      */
1166     _insertChild:function (child, z) {
1167         this._reorderChildDirty = true;
1168         this._children.push(child);
1169         child._setZOrder(z);
1170     },
1171 
1172     /** Reorders a child according to a new z value. <br/>
1173      * The child MUST be already added.
1174      * @param {cc.Node} child An already added child node. It MUST be already added.
1175      * @param {Number} zOrder Z order for drawing priority. Please refer to setZOrder(int)
1176      */
1177     reorderChild:function (child, zOrder) {
1178         if(!child)
1179             throw "cc.Node.reorderChild(): child must be non-null";
1180         this._reorderChildDirty = true;
1181         child.setOrderOfArrival(cc.s_globalOrderOfArrival++);
1182         child._setZOrder(zOrder);
1183         this.setNodeDirty();
1184     },
1185 
1186     /**
1187      * <p>
1188      *     Sorts the children array once before drawing, instead of every time when a child is added or reordered.    <br/>
1189      *     This approach can improves the performance massively.
1190      * </p>
1191      * @note Don't call this manually unless a child added needs to be removed in the same frame
1192      */
1193     sortAllChildren:function () {
1194         if (this._reorderChildDirty) {
1195             var _children = this._children;
1196             var i, j, length = _children.length,tempChild;
1197 
1198             // insertion sort
1199             for (i = 0; i < length; i++) {
1200                 var tempItem = _children[i];
1201                 j = i - 1;
1202                 tempChild =  _children[j];
1203 
1204                 //continue moving element downwards while zOrder is smaller or when zOrder is the same but mutatedIndex is smaller
1205                 while (j >= 0 && ( tempItem._zOrder < tempChild._zOrder ||
1206                     ( tempItem._zOrder == tempChild._zOrder && tempItem._orderOfArrival < tempChild._orderOfArrival ))) {
1207                     _children[j + 1] = tempChild;
1208                     j = j - 1;
1209                     tempChild =  _children[j];
1210                 }
1211                 _children[j + 1] = tempItem;
1212             }
1213 
1214             //don't need to check children recursively, that's done in visit of each child
1215             this._reorderChildDirty = false;
1216         }
1217     },
1218 
1219     // draw
1220     /** <p>Override this method to draw your own node. <br/>
1221      * The following GL states will be enabled by default: <br/>
1222      - glEnableClientState(GL_VERTEX_ARRAY);  <br/>
1223      - glEnableClientState(GL_COLOR_ARRAY); <br/>
1224      - glEnableClientState(GL_TEXTURE_COORD_ARRAY); <br/>
1225      - glEnable(GL_TEXTURE_2D); </p>
1226 
1227      <p>AND YOU SHOULD NOT DISABLE THEM AFTER DRAWING YOUR NODE</p>
1228 
1229      <p>But if you enable any other GL state, you should disable it after drawing your node. </p>
1230      * @param {CanvasContext} ctx
1231      */
1232     draw:function (ctx) {
1233         // override me
1234         // Only use- this function to draw your staff.
1235         // DON'T draw your stuff outside this method
1236     },
1237 
1238     /** performs OpenGL view-matrix transformation of it's ancestors.<br/>
1239      * Generally the ancestors are already transformed, but in certain cases (eg: attaching a FBO) <br/>
1240      * it's necessary to transform the ancestors again.
1241      */
1242     transformAncestors:function () {
1243         if (this._parent != null) {
1244             this._parent.transformAncestors();
1245             this._parent.transform();
1246         }
1247     },
1248 
1249     //scene managment
1250     /**
1251      * <p>
1252      *     Event callback that is invoked every time when CCNode enters the 'stage'.                                   <br/>
1253      *     If the CCNode enters the 'stage' with a transition, this event is called when the transition starts.        <br/>
1254      *     During onEnter you can't access a "sister/brother" node.                                                    <br/>
1255      *     If you override onEnter, you shall call its parent's one, e.g., CCNode::onEnter().
1256      * </p>
1257      */
1258     onEnter:function () {
1259         this._isTransitionFinished = false;
1260         this._running = true;//should be running before resumeSchedule
1261         this._arrayMakeObjectsPerformSelector(this._children, cc.Node.StateCallbackType.onEnter);
1262         this.resumeSchedulerAndActions();
1263     },
1264 
1265     /**
1266      * <p>
1267      *     Event callback that is invoked when the CCNode enters in the 'stage'.                                                        <br/>
1268      *     If the CCNode enters the 'stage' with a transition, this event is called when the transition finishes.                       <br/>
1269      *     If you override onEnterTransitionDidFinish, you shall call its parent's one, e.g. CCNode::onEnterTransitionDidFinish()
1270      * </p>
1271      */
1272     onEnterTransitionDidFinish:function () {
1273         this._isTransitionFinished = true;
1274         this._arrayMakeObjectsPerformSelector(this._children, cc.Node.StateCallbackType.onEnterTransitionDidFinish);
1275     },
1276 
1277     /**
1278      * <p>callback that is called every time the cc.Node leaves the 'stage'.  <br/>
1279      * If the cc.Node leaves the 'stage' with a transition, this callback is called when the transition starts. </p>
1280      */
1281     onExitTransitionDidStart:function () {
1282         this._arrayMakeObjectsPerformSelector(this._children, cc.Node.StateCallbackType.onExitTransitionDidStart);
1283     },
1284 
1285     /**
1286      * <p>
1287      * callback that is called every time the cc.Node leaves the 'stage'.                                         <br/>
1288      * If the cc.Node leaves the 'stage' with a transition, this callback is called when the transition finishes. <br/>
1289      * During onExit you can't access a sibling node.                                                             <br/>
1290      * If you override onExit, you shall call its parent's one, e.g., CCNode::onExit().
1291      * </p>
1292      */
1293     onExit:function () {
1294         this._running = false;
1295         this.pauseSchedulerAndActions();
1296         this._arrayMakeObjectsPerformSelector(this._children, cc.Node.StateCallbackType.onExit);
1297         if(this._componentContainer){
1298             this._componentContainer.removeAll();
1299         }
1300     },
1301 
1302     // actions
1303     /**
1304      * Executes an action, and returns the action that is executed.<br/>
1305      * The node becomes the action's target. Refer to CCAction::getTarget()
1306      * @warning Starting from v0.8 actions don't retain their target anymore.
1307      * @param {cc.Action} action
1308      * @return {cc.Action} An Action pointer
1309      */
1310     runAction:function (action) {
1311         if(!action)
1312             throw "cc.Node.runAction(): action must be non-null";
1313         this.getActionManager().addAction(action, this, !this._running);
1314         return action;
1315     },
1316 
1317     /**
1318      * Stops and removes all actions from the running action list .
1319      */
1320     stopAllActions:function () {
1321         this.getActionManager().removeAllActionsFromTarget(this);
1322     },
1323 
1324     /**
1325      * Stops and removes an action from the running action list.
1326      * @param {cc.Action} action An action object to be removed.
1327      */
1328     stopAction:function (action) {
1329         this.getActionManager().removeAction(action);
1330     },
1331 
1332     /**
1333      * Removes an action from the running action list by its tag.
1334      * @param {Number} tag A tag that indicates the action to be removed.
1335      */
1336     stopActionByTag:function (tag) {
1337         if(tag === cc.ACTION_TAG_INVALID){
1338             cc.log("cc.Node.stopActionBy(): argument tag an invalid tag");
1339             return;
1340         }
1341         this.getActionManager().removeActionByTag(tag, this);
1342     },
1343 
1344     /**
1345      * Gets an action from the running action list by its tag.
1346      * @see setTag(int), getTag().
1347      * @param {Number} tag
1348      * @return {cc.Action} The action object with the given tag.
1349      */
1350     getActionByTag:function (tag) {
1351         if(tag === cc.ACTION_TAG_INVALID){
1352             cc.log("cc.Node.getActionByTag(): argument tag is an invalid tag");
1353             return null;
1354         }
1355         return this.getActionManager().getActionByTag(tag, this);
1356     },
1357 
1358     /** Returns the numbers of actions that are running plus the ones that are schedule to run (actions in actionsToAdd and actions arrays).<br/>
1359      *    Composable actions are counted as 1 action. Example:<br/>
1360      *    If you are running 1 Sequence of 7 actions, it will return 1. <br/>
1361      *    If you are running 7 Sequences of 2 actions, it will return 7.
1362      * @return {Number} The number of actions that are running plus the ones that are schedule to run
1363      */
1364     getNumberOfRunningActions:function () {
1365         return this.getActionManager().numberOfRunningActionsInTarget(this);
1366     },
1367 
1368     // cc.Node - Callbacks
1369     // timers
1370     /**
1371      * schedules the "update" method.                                                                           <br/>
1372      * It will use the order number 0. This method will be called every frame.                                  <br/>
1373      * Scheduled methods with a lower order value will be called before the ones that have a higher order value.<br/>
1374      * Only one "update" method could be scheduled per node.
1375      */
1376     scheduleUpdate:function () {
1377         this.scheduleUpdateWithPriority(0);
1378     },
1379 
1380     /**
1381      * <p>
1382      * schedules the "update" callback function with a custom priority.
1383      * This callback function will be called every frame.<br/>
1384      * Scheduled callback functions with a lower priority will be called before the ones that have a higher value.<br/>
1385      * Only one "update" callback function could be scheduled per node (You can't have 2 'update' callback functions).<br/>
1386      * </p>
1387      * @param {Number} priority
1388      */
1389     scheduleUpdateWithPriority:function (priority) {
1390         this.getScheduler().scheduleUpdateForTarget(this, priority, !this._running);
1391     },
1392 
1393     /**
1394      * unschedules the "update" method.
1395      * @see scheduleUpdate();
1396      */
1397     unscheduleUpdate:function () {
1398         this.getScheduler().unscheduleUpdateForTarget(this);
1399     },
1400 
1401     /**
1402      * Schedules a custom selector.         <br/>
1403      * If the selector is already scheduled, then the interval parameter will be updated without scheduling it again.
1404      *
1405      * @param {function} callback_fn A function wrapped as a selector
1406      * @param {Number} interval  Tick interval in seconds. 0 means tick every frame. If interval = 0, it's recommended to use scheduleUpdate() instead.
1407      * @param {Number} repeat    The selector will be executed (repeat + 1) times, you can use kCCRepeatForever for tick infinitely.
1408      * @param {Number} delay     The amount of time that the first tick will wait before execution.
1409      */
1410     schedule:function (callback_fn, interval, repeat, delay) {
1411         interval = interval || 0;
1412 
1413         if(!callback_fn)
1414             throw "cc.Node.schedule(): callback function must be non-null";
1415         if(interval < 0)
1416             throw "cc.Node.schedule(): interval must be positive";
1417 
1418         repeat = (repeat == null) ? cc.REPEAT_FOREVER : repeat;
1419         delay = delay || 0;
1420 
1421         this.getScheduler().scheduleCallbackForTarget(this, callback_fn, interval, repeat, delay, !this._running);
1422     },
1423 
1424     /**
1425      * Schedules a callback function that runs only once, with a delay of 0 or larger
1426      * @see schedule(SEL_SCHEDULE, float, unsigned int, float)
1427      * @param {function} callback_fn  A function wrapped as a selector
1428      * @param {Number} delay  The amount of time that the first tick will wait before execution.
1429      */
1430     scheduleOnce:function (callback_fn, delay) {
1431         this.schedule(callback_fn, 0.0, 0, delay);
1432     },
1433 
1434     /**
1435      * unschedules a custom callback function.
1436      * @see schedule(SEL_SCHEDULE, float, unsigned int, float)
1437      * @param {function} callback_fn  A function wrapped as a selector
1438      */
1439     unschedule:function (callback_fn) {
1440         // explicit nil handling
1441         if (!callback_fn)
1442             return;
1443 
1444         this.getScheduler().unscheduleCallbackForTarget(this, callback_fn);
1445     },
1446 
1447     /**
1448      * unschedule all scheduled callback functions: custom callback functions, and the 'update' callback function.<br/>
1449      * Actions are not affected by this method.
1450      */
1451     unscheduleAllCallbacks:function () {
1452         this.getScheduler().unscheduleAllCallbacksForTarget(this);
1453     },
1454 
1455     /**
1456      * Resumes all scheduled selectors and actions.<br/>
1457      * This method is called internally by onEnter
1458      */
1459     resumeSchedulerAndActions:function () {
1460         this.getScheduler().resumeTarget(this);
1461         this.getActionManager().resumeTarget(this);
1462     },
1463 
1464     /**
1465      * Pauses all scheduled selectors and actions.<br/>
1466      * This method is called internally by onExit
1467      */
1468     pauseSchedulerAndActions:function () {
1469         this.getScheduler().pauseTarget(this);
1470         this.getActionManager().pauseTarget(this);
1471     },
1472 
1473     /**
1474      *<p>  Sets the additional transform.<br/>
1475      *  The additional transform will be concatenated at the end of nodeToParentTransform.<br/>
1476      *  It could be used to simulate `parent-child` relationship between two nodes (e.g. one is in BatchNode, another isn't).<br/>
1477      *  </p>
1478      *  @example
1479      * // create a batchNode
1480      * var batch= cc.SpriteBatchNode.create("Icon-114.png");
1481      * this.addChild(batch);
1482      *
1483      * // create two sprites, spriteA will be added to batchNode, they are using different textures.
1484      * var spriteA = cc.Sprite.createWithTexture(batch->getTexture());
1485      * var spriteB = cc.Sprite.create("Icon-72.png");
1486      *
1487      * batch.addChild(spriteA);
1488      *
1489      * // We can't make spriteB as spriteA's child since they use different textures. So just add it to layer.
1490      * // But we want to simulate `parent-child` relationship for these two node.
1491      * this.addChild(spriteB);
1492      *
1493      * //position
1494      * spriteA.setPosition(ccp(200, 200));
1495      *
1496      * // Gets the spriteA's transform.
1497      * var t = spriteA.nodeToParentTransform();
1498      *
1499      * // Sets the additional transform to spriteB, spriteB's position will based on its pseudo parent i.e. spriteA.
1500      * spriteB.setAdditionalTransform(t);
1501      *
1502      * //scale
1503      * spriteA.setScale(2);
1504      *
1505      * // Gets the spriteA's transform.
1506      * t = spriteA.nodeToParentTransform();
1507      *
1508      * // Sets the additional transform to spriteB, spriteB's scale will based on its pseudo parent i.e. spriteA.
1509      * spriteB.setAdditionalTransform(t);
1510      *
1511      * //rotation
1512      * spriteA.setRotation(20);
1513      *
1514      * // Gets the spriteA's transform.
1515      * t = spriteA.nodeToParentTransform();
1516      *
1517      * // Sets the additional transform to spriteB, spriteB's rotation will based on its pseudo parent i.e. spriteA.
1518      * spriteB.setAdditionalTransform(t);
1519      */
1520     setAdditionalTransform:function (additionalTransform) {
1521         this._additionalTransform = additionalTransform;
1522         this._transformDirty = true;
1523         this._additionalTransformDirty = true;
1524     },
1525 
1526     /**
1527      * Returns the matrix that transform parent's space coordinates to the node's (local) space coordinates.<br/>
1528      * The matrix is in Pixels.
1529      * @return {cc.AffineTransform}
1530      */
1531     parentToNodeTransform:function () {
1532         if (this._inverseDirty) {
1533             this._inverse = cc.AffineTransformInvert(this.nodeToParentTransform());
1534             this._inverseDirty = false;
1535         }
1536         return this._inverse;
1537     },
1538 
1539     /**
1540      *  Returns the world affine transform matrix. The matrix is in Pixels.
1541      * @return {cc.AffineTransform}
1542      */
1543     nodeToWorldTransform:function () {
1544         var t = this.nodeToParentTransform();
1545         for (var p = this._parent; p != null; p = p.getParent())
1546             t = cc.AffineTransformConcat(t, p.nodeToParentTransform());
1547         return t;
1548     },
1549 
1550     /**
1551      * Returns the inverse world affine transform matrix. The matrix is in Pixels.
1552      * @return {cc.AffineTransform}
1553      */
1554     worldToNodeTransform:function () {
1555         return cc.AffineTransformInvert(this.nodeToWorldTransform());
1556     },
1557 
1558     /**
1559      * Converts a Point to node (local) space coordinates. The result is in Points.
1560      * @param {cc.Point} worldPoint
1561      * @return {cc.Point}
1562      */
1563     convertToNodeSpace:function (worldPoint) {
1564         return cc.PointApplyAffineTransform(worldPoint, this.worldToNodeTransform());
1565     },
1566 
1567     /**
1568      * Converts a Point to world space coordinates. The result is in Points.
1569      * @param {cc.Point} nodePoint
1570      * @return {cc.Point}
1571      */
1572     convertToWorldSpace:function (nodePoint) {
1573         return cc.PointApplyAffineTransform(nodePoint, this.nodeToWorldTransform());
1574     },
1575 
1576     /**
1577      * Converts a Point to node (local) space coordinates. The result is in Points.<br/>
1578      * treating the returned/received node point as anchor relative.
1579      * @param {cc.Point} worldPoint
1580      * @return {cc.Point}
1581      */
1582     convertToNodeSpaceAR:function (worldPoint) {
1583         return cc.pSub(this.convertToNodeSpace(worldPoint), this._anchorPointInPoints);
1584     },
1585 
1586     /**
1587      * Converts a local Point to world space coordinates.The result is in Points.<br/>
1588      * treating the returned/received node point as anchor relative.
1589      * @param {cc.Point} nodePoint
1590      * @return {cc.Point}
1591      */
1592     convertToWorldSpaceAR:function (nodePoint) {
1593         var pt = cc.pAdd(nodePoint, this._anchorPointInPoints);
1594         return this.convertToWorldSpace(pt);
1595     },
1596 
1597     _convertToWindowSpace:function (nodePoint) {
1598         var worldPoint = this.convertToWorldSpace(nodePoint);
1599         return cc.Director.getInstance().convertToUI(worldPoint);
1600     },
1601 
1602     /** convenience methods which take a cc.Touch instead of cc.Point
1603      * @param {cc.Touch} touch
1604      * @return {cc.Point}
1605      */
1606     convertTouchToNodeSpace:function (touch) {
1607         var point = touch.getLocation();
1608         //TODO This point needn't convert to GL in HTML5
1609         //point = cc.Director.getInstance().convertToGL(point);
1610         return this.convertToNodeSpace(point);
1611     },
1612 
1613     /**
1614      * converts a cc.Touch (world coordinates) into a local coordiante. This method is AR (Anchor Relative).
1615      * @param {cc.Touch}touch
1616      * @return {cc.Point}
1617      */
1618     convertTouchToNodeSpaceAR:function (touch) {
1619         var point = touch.getLocation();
1620         point = cc.Director.getInstance().convertToGL(point);
1621         return this.convertToNodeSpaceAR(point);
1622     },
1623 
1624     /**
1625      * Update will be called automatically every frame if "scheduleUpdate" is called, and the node is "live" <br/>
1626      * (override me)
1627      * @param {Number} dt deltaTime
1628      */
1629     update:function (dt) {
1630         if(this._componentContainer && !this._componentContainer.isEmpty())
1631             this._componentContainer.visit(dt);
1632     },
1633 
1634     /**
1635      * <p>
1636      * Calls children's updateTransform() method recursively.                                        <br/>
1637      *                                                                                               <br/>
1638      * This method is moved from CCSprite, so it's no longer specific to CCSprite.                   <br/>
1639      * As the result, you apply CCSpriteBatchNode's optimization on your customed CCNode.            <br/>
1640      * e.g., batchNode->addChild(myCustomNode), while you can only addChild(sprite) before.
1641      * </p>
1642      */
1643     updateTransform:function () {
1644         // Recursively iterate over children
1645         this._arrayMakeObjectsPerformSelector(this._children, cc.Node.StateCallbackType.updateTransform);
1646     },
1647 
1648     /**
1649      * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB,
1650      * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB.
1651      * This is a hack, and should be removed once JSB fixes the retain/release bug
1652      */
1653     retain:function () {
1654     },
1655     release:function () {
1656     },
1657 
1658     /**
1659      * gets a component by its name
1660      * @param {String} name
1661      * @return {cc.Component} gets a component by its name
1662      */
1663     getComponent:function(name){
1664         return this._componentContainer.getComponent(name);
1665     },
1666 
1667     /**
1668      * adds a component
1669      * @param {cc.Component} component
1670      */
1671     addComponent:function(component){
1672         this._componentContainer.add(component);
1673     },
1674 
1675     /**
1676      * removes a component by its name or a component
1677      * @param {String|cc.Component} name
1678      */
1679     removeComponent:function(name){
1680         return this._componentContainer.remove(name);
1681     },
1682 
1683     /**
1684      * removes all components
1685      */
1686     removeAllComponents:function(){
1687         this._componentContainer.removeAll();
1688     },
1689 
1690     _transform4x4:null,
1691     _stackMatrix:null,
1692     _glServerState:null,
1693     _camera:null,
1694     _grid:null,
1695 
1696     /**
1697      * Constructor
1698      */
1699     ctor: null,
1700 
1701     _ctorForCanvas: function () {
1702         this._initNode();
1703 
1704         //Canvas
1705     },
1706 
1707     _ctorForWebGL: function () {
1708         this._initNode();
1709 
1710         //WebGL
1711         var mat4 = new cc.kmMat4();
1712         mat4.mat[2] = mat4.mat[3] = mat4.mat[6] = mat4.mat[7] = mat4.mat[8] = mat4.mat[9] = mat4.mat[11] = mat4.mat[14] = 0.0;
1713         mat4.mat[10] = mat4.mat[15] = 1.0;
1714         this._transform4x4 = mat4;
1715         this._glServerState = 0;
1716         this._stackMatrix = new cc.kmMat4();
1717     },
1718 
1719     /**
1720      * recursive method that visit its children and draw them
1721      * @param {CanvasRenderingContext2D|WebGLRenderingContext} ctx
1722      */
1723     visit:null,
1724 
1725     _visitForCanvas:function (ctx) {
1726         // quick return if not visible
1727         if (!this._visible)
1728             return;
1729 
1730         //visit for canvas
1731         var context = ctx || cc.renderContext, i;
1732         var children = this._children,child;
1733         context.save();
1734         this.transform(context);
1735         var len = children.length;
1736         if (len > 0) {
1737             this.sortAllChildren();
1738             // draw children zOrder < 0
1739             for (i = 0; i < len; i++) {
1740                 child = children[i];
1741                 if (child._zOrder < 0)
1742                     child.visit(context);
1743                 else
1744                     break;
1745             }
1746             this.draw(context);
1747             for (; i < len; i++) {
1748                 children[i].visit(context);
1749             }
1750         } else
1751             this.draw(context);
1752 
1753         this._orderOfArrival = 0;
1754         context.restore();
1755     },
1756 
1757     _visitForWebGL: function(){
1758         // quick return if not visible
1759         if (!this._visible)
1760             return;
1761         var context = cc.renderContext, i, currentStack = cc.current_stack;
1762 
1763         //cc.kmGLPushMatrixWitMat4(this._stackMatrix);
1764         //optimize performance for javascript
1765         currentStack.stack.push(currentStack.top);
1766         cc.kmMat4Assign(this._stackMatrix, currentStack.top);
1767         currentStack.top = this._stackMatrix;
1768 
1769         var locGrid = this._grid;
1770         if (locGrid && locGrid._active)
1771             locGrid.beforeDraw();
1772 
1773         this.transform();
1774 
1775         var locChildren = this._children;
1776         if (locChildren && locChildren.length > 0) {
1777             var childLen = locChildren.length;
1778             this.sortAllChildren();
1779             // draw children zOrder < 0
1780             for (i = 0; i < childLen; i++) {
1781                 if (locChildren[i] && locChildren[i]._zOrder < 0)
1782                     locChildren[i].visit();
1783                 else
1784                     break;
1785             }
1786             this.draw(context);
1787             // draw children zOrder >= 0
1788             for (; i < childLen; i++) {
1789                 if (locChildren[i]) {
1790                     locChildren[i].visit();
1791                 }
1792             }
1793         } else
1794             this.draw(context);
1795 
1796         this._orderOfArrival = 0;
1797         if (locGrid && locGrid._active)
1798             locGrid.afterDraw(this);
1799 
1800         //cc.kmGLPopMatrix();
1801         //optimize performance for javascript
1802         currentStack.top = currentStack.stack.pop();
1803     },
1804 
1805     /**
1806      * Performs OpenGL view-matrix transformation based on position, scale, rotation and other attributes.
1807      */
1808     transform:null,
1809 
1810     _transformForCanvas: function (ctx) {
1811         // transform for canvas
1812         var context = ctx || cc.renderContext, eglViewer = cc.EGLView.getInstance();
1813 
1814         var t = this.nodeToParentTransform();
1815         context.transform(t.a, t.c, t.b, t.d, t.tx * eglViewer.getScaleX(), -t.ty * eglViewer.getScaleY());
1816     },
1817 
1818     _transformForWebGL: function () {
1819         //optimize performance for javascript
1820         var t4x4 = this._transform4x4,  topMat4 = cc.current_stack.top;
1821 
1822         // Convert 3x3 into 4x4 matrix
1823         //cc.CGAffineToGL(this.nodeToParentTransform(), this._transform4x4.mat);
1824         var trans = this.nodeToParentTransform();
1825         var t4x4Mat = t4x4.mat;
1826         t4x4Mat[0] = trans.a;
1827         t4x4Mat[4] = trans.c;
1828         t4x4Mat[12] = trans.tx;
1829         t4x4Mat[1] = trans.b;
1830         t4x4Mat[5] = trans.d;
1831         t4x4Mat[13] = trans.ty;
1832 
1833         // Update Z vertex manually
1834         //this._transform4x4.mat[14] = this._vertexZ;
1835         t4x4Mat[14] = this._vertexZ;
1836 
1837         //optimize performance for Javascript
1838         cc.kmMat4Multiply(topMat4, topMat4, t4x4); // = cc.kmGLMultMatrix(this._transform4x4);
1839 
1840         // XXX: Expensive calls. Camera should be integrated into the cached affine matrix
1841         if (this._camera != null && !(this._grid != null && this._grid.isActive())) {
1842             var apx = this._anchorPointInPoints.x, apy = this._anchorPointInPoints.y;
1843             var translate = (apx !== 0.0 || apy !== 0.0);
1844             if (translate){
1845                 cc.kmGLTranslatef(cc.RENDER_IN_SUBPIXEL(apx), cc.RENDER_IN_SUBPIXEL(apy), 0);
1846                 this._camera.locate();
1847                 cc.kmGLTranslatef(cc.RENDER_IN_SUBPIXEL(-apx), cc.RENDER_IN_SUBPIXEL(-apy), 0);
1848             } else {
1849                 this._camera.locate();
1850             }
1851         }
1852     },
1853 
1854     /** Returns the matrix that transform the node's (local) space coordinates into the parent's space coordinates.<br/>
1855      * The matrix is in Pixels.
1856      * @return {cc.AffineTransform}
1857      */
1858     nodeToParentTransform: null,
1859 
1860     _nodeToParentTransformForCanvas:function () {
1861         if (this._transformDirty) {
1862             var t = this._transform;// quick reference
1863 
1864             // base position
1865             t.tx = this._position.x;
1866             t.ty = this._position.y;
1867 
1868             // rotation Cos and Sin
1869             var Cos = 1, Sin = 0;
1870             if (this._rotationX) {
1871                 Cos = Math.cos(this._rotationRadiansX);
1872                 Sin = Math.sin(this._rotationRadiansX);
1873             }
1874 
1875             // base abcd
1876             t.a = t.d = Cos;
1877             t.b = -Sin;
1878             t.c = Sin;
1879 
1880             var lScaleX = this._scaleX, lScaleY = this._scaleY;
1881             var appX = this._anchorPointInPoints.x, appY = this._anchorPointInPoints.y;
1882 
1883             // Firefox on Vista and XP crashes
1884             // GPU thread in case of scale(0.0, 0.0)
1885             var sx = (lScaleX < 0.000001 && lScaleX > -0.000001)?  0.000001 : lScaleX,
1886                 sy = (lScaleY < 0.000001 && lScaleY > -0.000001)? 0.000001 : lScaleY;
1887 
1888             // skew
1889             if (this._skewX || this._skewY) {
1890                 // offset the anchorpoint
1891                 var skx = Math.tan(-this._skewX * Math.PI / 180);
1892                 var sky = Math.tan(-this._skewY * Math.PI / 180);
1893                 var xx = appY * skx * sx;
1894                 var yy = appX * sky * sy;
1895                 t.a = Cos + -Sin * sky;
1896                 t.b = Cos * skx + -Sin;
1897                 t.c = Sin + Cos * sky;
1898                 t.d = Sin * skx + Cos;
1899                 t.tx += Cos * xx + -Sin * yy;
1900                 t.ty += Sin * xx + Cos * yy;
1901             }
1902 
1903             // scale
1904             if (lScaleX !== 1 || lScaleY !== 1) {
1905                 t.a *= sx;
1906                 t.c *= sx;
1907                 t.b *= sy;
1908                 t.d *= sy;
1909             }
1910 
1911             // adjust anchorPoint
1912             t.tx += Cos * -appX * sx + -Sin * appY * sy;
1913             t.ty -= Sin * -appX * sx + Cos * appY * sy;
1914 
1915             // if ignore anchorPoint
1916             if (this._ignoreAnchorPointForPosition) {
1917                 t.tx += appX;
1918                 t.ty += appY;
1919             }
1920 
1921             if (this._additionalTransformDirty) {
1922                 this._transform = cc.AffineTransformConcat(t, this._additionalTransform);
1923                 this._additionalTransformDirty = false;
1924             }
1925 
1926             this._transformDirty = false;
1927         }
1928         return this._transform;
1929     },
1930 
1931     _nodeToParentTransformForWebGL:function () {
1932         if (this._transformDirty) {
1933             // Translate values
1934             var x = this._position.x;
1935             var y = this._position.y;
1936             var apx = this._anchorPointInPoints.x, napx = -apx;
1937             var apy = this._anchorPointInPoints.y, napy = -apy;
1938             var scx = this._scaleX, scy = this._scaleY;
1939 
1940             if (this._ignoreAnchorPointForPosition) {
1941                 x += apx;
1942                 y += apy;
1943             }
1944 
1945             // Rotation values
1946             // Change rotation code to handle X and Y
1947             // If we skew with the exact same value for both x and y then we're simply just rotating
1948             var cx = 1, sx = 0, cy = 1, sy = 0;
1949             if (this._rotationX !== 0 || this._rotationY !== 0) {
1950                 cx = Math.cos(-this._rotationRadiansX);
1951                 sx = Math.sin(-this._rotationRadiansX);
1952                 cy = Math.cos(-this._rotationRadiansY);
1953                 sy = Math.sin(-this._rotationRadiansY);
1954             }
1955             var needsSkewMatrix = ( this._skewX || this._skewY );
1956 
1957             // optimization:
1958             // inline anchor point calculation if skew is not needed
1959             // Adjusted transform calculation for rotational skew
1960             if (!needsSkewMatrix && (apx !== 0 || apy !== 0)) {
1961                 x += cy * napx * scx + -sx * napy * scy;
1962                 y += sy * napx * scx + cx * napy * scy;
1963             }
1964 
1965             // Build Transform Matrix
1966             // Adjusted transform calculation for rotational skew
1967             var t = this._transform;
1968             t.a = cy * scx;
1969             t.b = sy * scx;
1970             t.c = -sx * scy;
1971             t.d = cx * scy;
1972             t.tx = x;
1973             t.ty = y;
1974 
1975             // XXX: Try to inline skew
1976             // If skew is needed, apply skew and then anchor point
1977             if (needsSkewMatrix) {
1978                 t = cc.AffineTransformConcat({a: 1.0, b: Math.tan(cc.DEGREES_TO_RADIANS(this._skewY)),
1979                     c: Math.tan(cc.DEGREES_TO_RADIANS(this._skewX)), d: 1.0, tx: 0.0, ty: 0.0}, t);
1980 
1981                 // adjust anchor point
1982                 if (apx !== 0 || apy !== 0)
1983                     t = cc.AffineTransformTranslate(t, napx, napy);
1984             }
1985 
1986             if (this._additionalTransformDirty) {
1987                 t = cc.AffineTransformConcat(t, this._additionalTransform);
1988                 this._additionalTransformDirty = false;
1989             }
1990             this._transform = t;
1991             this._transformDirty = false;
1992         }
1993         return this._transform;
1994     },
1995 
1996     _setNodeDirtyForCache:function () {
1997         this._cacheDirty = true;
1998         if (this._parent) {
1999             this._parent._setNodeDirtyForCache();
2000         }
2001     },
2002 
2003     /**
2004      * Returns a camera object that lets you move the node using a gluLookAt
2005      * @return {cc.Camera} A CCCamera object that lets you move the node using a gluLookAt
2006      * @example
2007      * var camera = node.getCamera();
2008      * camera.setEye(0, 0, 415/2);
2009      * camera.setCenter(0, 0, 0);
2010      */
2011     getCamera:function () {
2012         if (!this._camera) {
2013             this._camera = new cc.Camera();
2014         }
2015         return this._camera;
2016     },
2017 
2018     /**
2019      * Returns a grid object that is used when applying effects
2020      * @return {cc.GridBase} A CCGrid object that is used when applying effects
2021      */
2022     getGrid:function () {
2023         return this._grid;
2024     },
2025 
2026     /**
2027      * Changes a grid object that is used when applying effects
2028      * @param {cc.GridBase} grid A CCGrid object that is used when applying effects
2029      */
2030     setGrid:function (grid) {
2031         this._grid = grid;
2032     },
2033 
2034     /**
2035      * Return the shader program currently used for this node
2036      * @return {cc.GLProgram} The shader program currelty used for this node
2037      */
2038     getShaderProgram:function () {
2039         return this._shaderProgram;
2040     },
2041 
2042     /**
2043      * <p>
2044      *     Sets the shader program for this node
2045      *
2046      *     Since v2.0, each rendering node must set its shader program.
2047      *     It should be set in initialize phase.
2048      * </p>
2049      * @param {cc.GLProgram} newShaderProgram The shader program which fetchs from CCShaderCache.
2050      * @example
2051      *  node.setShaderProgram(cc.ShaderCache.getInstance().programForKey(cc.SHADER_POSITION_TEXTURECOLOR));
2052      */
2053     setShaderProgram:function (newShaderProgram) {
2054         this._shaderProgram = newShaderProgram;
2055     },
2056 
2057     /**
2058      * Returns the state of OpenGL server side.
2059      * @return {Number} The state of OpenGL server side.
2060      */
2061     getGLServerState:function () {
2062         return this._glServerState;
2063     },
2064 
2065     /**
2066      * Sets the state of OpenGL server side.
2067      * @param {Number} state The state of OpenGL server side.
2068      */
2069     setGLServerState:function (state) {
2070         this._glServerState = state;
2071     },
2072 
2073     /** returns a "world" axis aligned bounding box of the node. <br/>
2074      * @return {cc.Rect}
2075      */
2076     getBoundingBoxToWorld:function () {
2077         var rect = cc.rect(0, 0, this._contentSize.width, this._contentSize.height);
2078         var trans = this.nodeToWorldTransform();
2079         rect = cc.RectApplyAffineTransform(rect, this.nodeToWorldTransform());
2080         //rect = cc.rect(0 | rect.x - 4, 0 | rect.y - 4, 0 | rect.width + 8, 0 | rect.height + 8);
2081 
2082         //query child's BoundingBox
2083         if (!this._children)
2084             return rect;
2085 
2086         var locChildren = this._children;
2087         for (var i = 0; i < locChildren.length; i++) {
2088             var child = locChildren[i];
2089             if (child && child._visible) {
2090                 var childRect = child._getBoundingBoxToCurrentNode(trans);
2091                 if (childRect)
2092                     rect = cc.rectUnion(rect, childRect);
2093             }
2094         }
2095         return rect;
2096     },
2097 
2098     _getBoundingBoxToCurrentNode: function (parentTransform) {
2099         var rect = cc.rect(0, 0, this._contentSize.width, this._contentSize.height);
2100         var trans = (parentTransform == null) ? this.nodeToParentTransform() : cc.AffineTransformConcat(this.nodeToParentTransform(), parentTransform);
2101         rect = cc.RectApplyAffineTransform(rect, trans);
2102 
2103         //query child's BoundingBox
2104         if (!this._children)
2105             return rect;
2106 
2107         var locChildren = this._children;
2108         for (var i = 0; i < locChildren.length; i++) {
2109             var child = locChildren[i];
2110             if (child && child._visible) {
2111                 var childRect = child._getBoundingBoxToCurrentNode(trans);
2112                 if (childRect)
2113                     rect = cc.rectUnion(rect, childRect);
2114             }
2115         }
2116         return rect;
2117     }
2118 });
2119 
2120 if(cc.Browser.supportWebGL){
2121     //WebGL
2122     cc.Node.prototype.ctor = cc.Node.prototype._ctorForWebGL;
2123     cc.Node.prototype.setNodeDirty = cc.Node.prototype._setNodeDirtyForWebGL;
2124     cc.Node.prototype.visit = cc.Node.prototype._visitForWebGL;
2125     cc.Node.prototype.transform = cc.Node.prototype._transformForWebGL;
2126     cc.Node.prototype.nodeToParentTransform = cc.Node.prototype._nodeToParentTransformForWebGL;
2127 }else{
2128     //Canvas
2129     cc.Node.prototype.ctor = cc.Node.prototype._ctorForCanvas;
2130     cc.Node.prototype.setNodeDirty = cc.Node.prototype._setNodeDirtyForCanvas;
2131     cc.Node.prototype.visit = cc.Node.prototype._visitForCanvas;
2132     cc.Node.prototype.transform = cc.Node.prototype._transformForCanvas;
2133     cc.Node.prototype.nodeToParentTransform = cc.Node.prototype._nodeToParentTransformForCanvas;
2134 }
2135 
2136 /**
2137  * allocates and initializes a node.
2138  * @constructs
2139  * @return {cc.Node}
2140  * @example
2141  * // example
2142  * var node = cc.Node.create();
2143  */
2144 cc.Node.create = function () {
2145     return new cc.Node();
2146 };
2147 
2148 /**
2149  * cc.Node's state callback type
2150  * @constant
2151  * @type Number
2152  */
2153 cc.Node.StateCallbackType = {onEnter:1, onExit:2, cleanup:3, onEnterTransitionDidFinish:4, updateTransform:5, onExitTransitionDidStart:6, sortAllChildren:7};
2154 
2155 /**
2156  * <p>
2157  *     cc.NodeRGBA is a subclass of cc.Node that implements the CCRGBAProtocol protocol.                       <br/>
2158  *     <br/>
2159  *     All features from CCNode are valid, plus the following new features:                                     <br/>
2160  *      - opacity                                                                                               <br/>
2161  *      - RGB colors                                                                                            <br/>
2162  *     <br/>
2163  *     Opacity/Color propagates into children that conform to the CCRGBAProtocol if cascadeOpacity/cascadeColor is enabled.   <br/>
2164  * </p>
2165  *
2166  * @class
2167  * @extends cc.Node
2168  */
2169 cc.NodeRGBA = cc.Node.extend(/** @lends cc.NodeRGBA# */{
2170     RGBAProtocol:true,
2171     _displayedOpacity:255,
2172     _realOpacity:255,
2173     _displayedColor:null,
2174     _realColor:null,
2175     _cascadeColorEnabled:false,
2176     _cascadeOpacityEnabled:false,
2177 
2178     ctor:function(){
2179         cc.Node.prototype.ctor.call(this);
2180         this._displayedOpacity = 255;
2181         this._realOpacity = 255;
2182         this._displayedColor = cc.white();
2183         this._realColor = cc.white();
2184         this._cascadeColorEnabled = false;
2185         this._cascadeOpacityEnabled = false;
2186     },
2187 
2188     /**
2189      * Get the opacity of Node
2190      * @returns {number} opacity
2191      */
2192     getOpacity:function(){
2193         return this._realOpacity;
2194     },
2195 
2196     /**
2197      * Get the displayed opacity of Node
2198      * @returns {number} displayed opacity
2199      */
2200     getDisplayedOpacity:function(){
2201         return this._displayedOpacity;
2202     },
2203 
2204     /**
2205      * Set the opacity of Node
2206      * @param {Number} opacity
2207      */
2208     setOpacity:function(opacity){
2209         this._displayedOpacity = this._realOpacity = opacity;
2210 
2211         var parentOpacity = 255, locParent = this._parent;
2212         if (locParent && locParent.RGBAProtocol && locParent.isCascadeOpacityEnabled())
2213             parentOpacity = locParent.getDisplayedOpacity();
2214         this.updateDisplayedOpacity(parentOpacity);
2215     },
2216 
2217     /**
2218      * Update displayed opacity
2219      * @param {Number} parentOpacity
2220      */
2221     updateDisplayedOpacity: function (parentOpacity) {
2222         this._displayedOpacity = this._realOpacity * parentOpacity / 255.0;
2223         if (this._cascadeOpacityEnabled) {
2224             var selChildren = this._children;
2225             for (var i = 0; i < selChildren.length; i++) {
2226                 var item = selChildren[i];
2227                 if (item && item.RGBAProtocol)
2228                     item.updateDisplayedOpacity(this._displayedOpacity);
2229             }
2230         }
2231     },
2232 
2233     /**
2234      * whether or not it will set cascade opacity.
2235      * @returns {boolean}
2236      */
2237     isCascadeOpacityEnabled:function(){
2238         return this._cascadeOpacityEnabled;
2239     },
2240 
2241     /**
2242      * Enable or disable cascade opacity
2243      * @param {boolean} cascadeOpacityEnabled
2244      */
2245     setCascadeOpacityEnabled:function(cascadeOpacityEnabled){
2246         if(this._cascadeOpacityEnabled === cascadeOpacityEnabled)
2247             return;
2248 
2249         this._cascadeOpacityEnabled = cascadeOpacityEnabled;
2250         if(cascadeOpacityEnabled)
2251             this._enableCascadeOpacity();
2252         else
2253             this._disableCascadeOpacity();
2254     },
2255 
2256     _enableCascadeOpacity:function(){
2257         var parentOpacity = 255, locParent = this._parent;
2258         if (locParent && locParent.RGBAProtocol && locParent.isCascadeOpacityEnabled())
2259             parentOpacity = locParent.getDisplayedOpacity();
2260         this.updateDisplayedOpacity(parentOpacity);
2261     },
2262 
2263     _disableCascadeOpacity:function(){
2264         this._displayedOpacity = this._realOpacity;
2265 
2266         var selChildren = this._children;
2267         for(var i = 0; i< selChildren.length;i++){
2268             var item = selChildren[i];
2269             if(item && item.RGBAProtocol)
2270                 item.updateDisplayedOpacity(255);
2271         }
2272     },
2273 
2274     /**
2275      * Get the color of Node
2276      * @returns {cc.Color3B}
2277      */
2278     getColor:function(){
2279         var locRealColor = this._realColor;
2280         return new cc.Color3B(locRealColor.r, locRealColor.g, locRealColor.b);
2281     },
2282 
2283     /**
2284      * Get the displayed color of Node
2285      * @returns {cc.Color3B}
2286      */
2287     getDisplayedColor:function(){
2288         return this._displayedColor;
2289     },
2290 
2291     /**
2292      * Set the color of Node
2293      * @param {cc.Color3B} color
2294      */
2295     setColor:function(color){
2296         var locDisplayedColor = this._displayedColor, locRealColor = this._realColor;
2297         locDisplayedColor.r = locRealColor.r = color.r;
2298         locDisplayedColor.g = locRealColor.g = color.g;
2299         locDisplayedColor.b = locRealColor.b = color.b;
2300 
2301         var parentColor, locParent = this._parent;
2302         if (locParent && locParent.RGBAProtocol && locParent.isCascadeColorEnabled())
2303             parentColor = locParent.getDisplayedColor();
2304         else
2305             parentColor = cc.white();
2306         this.updateDisplayedColor(parentColor);
2307     },
2308 
2309     /**
2310      * update the displayed color of Node
2311      * @param {cc.Color3B} parentColor
2312      */
2313     updateDisplayedColor: function (parentColor) {
2314         var locDispColor = this._displayedColor, locRealColor = this._realColor;
2315         locDispColor.r = 0 | (locRealColor.r * parentColor.r / 255.0);
2316         locDispColor.g = 0 | (locRealColor.g * parentColor.g / 255.0);
2317         locDispColor.b = 0 | (locRealColor.b * parentColor.b / 255.0);
2318 
2319         if (this._cascadeColorEnabled) {
2320             var selChildren = this._children;
2321             for (var i = 0; i < selChildren.length; i++) {
2322                 var item = selChildren[i];
2323                 if (item && item.RGBAProtocol)
2324                     item.updateDisplayedColor(locDispColor);
2325             }
2326         }
2327     },
2328 
2329     /**
2330      * whether or not it will set cascade color.
2331      * @returns {boolean}
2332      */
2333     isCascadeColorEnabled:function(){
2334         return this._cascadeColorEnabled;
2335     },
2336 
2337     /**
2338      * Enable or disable cascade color
2339      * @param {boolean} cascadeColorEnabled
2340      */
2341     setCascadeColorEnabled:function(cascadeColorEnabled){
2342         if(this._cascadeColorEnabled === cascadeColorEnabled)
2343             return;
2344         this._cascadeColorEnabled = cascadeColorEnabled;
2345         if(this._cascadeColorEnabled)
2346             this._enableCascadeColor();
2347         else
2348             this._disableCascadeColor();
2349     },
2350 
2351     _enableCascadeColor: function(){
2352         var parentColor , locParent =  this._parent;
2353         if (locParent && locParent.RGBAProtocol &&  locParent.isCascadeColorEnabled())
2354             parentColor = locParent.getDisplayedColor();
2355         else
2356             parentColor = cc.white();
2357         this.updateDisplayedColor(parentColor);
2358     },
2359 
2360     _disableCascadeColor: function(){
2361         var locDisplayedColor = this._displayedColor, locRealColor = this._realColor;
2362         locDisplayedColor.r = locRealColor.r;
2363         locDisplayedColor.g = locRealColor.g;
2364         locDisplayedColor.b = locRealColor.b;
2365 
2366         var selChildren = this._children, whiteColor = cc.white();
2367         for(var i = 0; i< selChildren.length;i++){
2368             var item = selChildren[i];
2369             if(item && item.RGBAProtocol)
2370                 item.updateDisplayedColor(whiteColor);
2371         }
2372     },
2373 
2374     /**
2375      * add a child to node
2376      * @overried
2377      * @param {cc.Node} child  A child node
2378      * @param {Number} [zOrder=]  Z order for drawing priority. Please refer to setZOrder(int)
2379      * @param {Number} [tag=]  A integer to identify the node easily. Please refer to setTag(int)
2380      */
2381     addChild:function(child, zOrder, tag){
2382         cc.Node.prototype.addChild.call(this, child, zOrder, tag);
2383 
2384         if(this._cascadeColorEnabled)
2385             this._enableCascadeColor();
2386         if(this._cascadeOpacityEnabled)
2387             this._enableCascadeOpacity();
2388     },
2389 
2390     setOpacityModifyRGB:function(opacityValue){},
2391 
2392     isOpacityModifyRGB:function(){
2393         return false;
2394     }
2395 });
2396 cc.NodeRGBA.create = function () {
2397     var res = new cc.NodeRGBA();
2398     res.init();
2399     return res;
2400 };
2401