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