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