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