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