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