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