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