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