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 /** cc.Layer is a subclass of cc.Node that implements the TouchEventsDelegate protocol.<br/>
 28  * All features from cc.Node are valid, plus the bake feature: Baked layer can cache a static layer to improve performance
 29  * @class
 30  * @extends cc.Node
 31  */
 32 cc.Layer = cc.Node.extend(/** @lends cc.Layer# */{
 33     _className: "Layer",
 34 
 35     /**
 36      * <p>Constructor of cc.Layer, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.</p>
 37      */
 38     ctor: function () {
 39         cc.Node.prototype.ctor.call(this);
 40         this._ignoreAnchorPointForPosition = true;
 41         this.setAnchorPoint(0.5, 0.5);
 42         this.setContentSize(cc.winSize);
 43     },
 44 
 45     /**
 46      * Initialization of the layer, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer
 47      */
 48     init: function(){
 49         var _t = this;
 50         _t._ignoreAnchorPointForPosition = true;
 51         _t.setAnchorPoint(0.5, 0.5);
 52         _t.setContentSize(cc.winSize);
 53         _t._cascadeColorEnabled = false;
 54         _t._cascadeOpacityEnabled = false;
 55         return true;
 56     },
 57 
 58     /**
 59      * Sets the layer to cache all of children to a bake sprite, and draw itself by bake sprite. recommend using it in UI.<br/>
 60      * This is useful only in html5 engine
 61      * @function
 62      * @see cc.Layer#unbake
 63      */
 64     bake: function(){
 65         this._renderCmd.bake();
 66     },
 67 
 68     /**
 69      * Cancel the layer to cache all of children to a bake sprite.<br/>
 70      * This is useful only in html5 engine
 71      * @function
 72      * @see cc.Layer#bake
 73      */
 74     unbake: function(){
 75         this._renderCmd.unbake();
 76     },
 77 
 78     /**
 79      * Determines if the layer is baked.
 80      * @function
 81      * @returns {boolean}
 82      * @see cc.Layer#bake and cc.Layer#unbake
 83      */
 84     isBaked: function(){
 85         return this._renderCmd._isBaked;
 86     },
 87 
 88     addChild: function(child, localZOrder, tag){
 89         cc.Node.prototype.addChild.call(this, child, localZOrder, tag);
 90         this._renderCmd._bakeForAddChild(child);
 91     },
 92 
 93     _createRenderCmd: function(){
 94         if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
 95             return new cc.Layer.CanvasRenderCmd(this);
 96         else
 97             return new cc.Layer.WebGLRenderCmd(this);
 98     }
 99 });
100 
101 /**
102  * Creates a layer
103  * @deprecated since v3.0, please use the new construction instead
104  * @see cc.Layer
105  * @return {cc.Layer|Null}
106  */
107 cc.Layer.create = function () {
108     return new cc.Layer();
109 };
110 
111 /**
112  * <p>
113  * CCLayerColor is a subclass of CCLayer that implements the CCRGBAProtocol protocol.       <br/>
114  *  All features from CCLayer are valid, plus the following new features:                   <br/>
115  * - opacity                                                                     <br/>
116  * - RGB colors                                                                  </p>
117  * @class
118  * @extends cc.Layer
119  *
120  * @param {cc.Color} [color=] The color of the layer
121  * @param {Number} [width=] The width of the layer
122  * @param {Number} [height=] The height of the layer
123  *
124  * @example
125  * // Example
126  * //Create a yellow color layer as background
127  * var yellowBackground = new cc.LayerColor(cc.color(255,255,0,255));
128  * //If you didn't pass in width and height, it defaults to the same size as the canvas
129  *
130  * //create a yellow box, 200 by 200 in size
131  * var yellowBox = new cc.LayerColor(cc.color(255,255,0,255), 200, 200);
132  */
133 cc.LayerColor = cc.Layer.extend(/** @lends cc.LayerColor# */{
134     _blendFunc: null,
135     _className: "LayerColor",
136 
137     /**
138      * Returns the blend function
139      * @return {cc.BlendFunc}
140      */
141     getBlendFunc: function () {
142         return this._blendFunc;
143     },
144 
145     /**
146      * Changes width and height
147      * @deprecated since v3.0 please use setContentSize instead
148      * @see cc.Node#setContentSize
149      * @param {Number} w width
150      * @param {Number} h height
151      */
152     changeWidthAndHeight: function (w, h) {
153         this.width = w;
154         this.height = h;
155     },
156 
157     /**
158      * Changes width in Points
159      * @deprecated since v3.0 please use setContentSize instead
160      * @see cc.Node#setContentSize
161      * @param {Number} w width
162      */
163     changeWidth: function (w) {
164         this.width = w;
165     },
166 
167     /**
168      * change height in Points
169      * @deprecated since v3.0 please use setContentSize instead
170      * @see cc.Node#setContentSize
171      * @param {Number} h height
172      */
173     changeHeight: function (h) {
174         this.height = h;
175     },
176 
177     setOpacityModifyRGB: function (value) {
178     },
179 
180     isOpacityModifyRGB: function () {
181         return false;
182     },
183 
184     /**
185      * Constructor of cc.LayerColor
186      * @function
187      * @param {cc.Color} [color=]
188      * @param {Number} [width=]
189      * @param {Number} [height=]
190      */
191     ctor: function(color, width, height){
192         cc.Layer.prototype.ctor.call(this);
193         this._blendFunc = cc.BlendFunc._alphaNonPremultiplied();
194         cc.LayerColor.prototype.init.call(this, color, width, height);
195     },
196 
197     /**
198      * Initialization of the layer, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer
199      * @param {cc.Color} [color=]
200      * @param {Number} [width=]
201      * @param {Number} [height=]
202      * @return {Boolean}
203      */
204     init: function (color, width, height) {
205         var winSize = cc.director.getWinSize();
206         color = color || cc.color(0, 0, 0, 255);
207         width = width === undefined ? winSize.width : width;
208         height = height === undefined ? winSize.height : height;
209 
210         var locRealColor = this._realColor;
211         locRealColor.r = color.r;
212         locRealColor.g = color.g;
213         locRealColor.b = color.b;
214         this._realOpacity = color.a;
215         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty|cc.Node._dirtyFlags.opacityDirty);
216 
217         cc.LayerColor.prototype.setContentSize.call(this, width, height);
218         return true;
219     },
220 
221     /**
222      * Sets the blend func, you can pass either a cc.BlendFunc object or source and destination value separately
223      * @param {Number|cc.BlendFunc} src
224      * @param {Number} [dst]
225      */
226     setBlendFunc: function (src, dst) {
227         var locBlendFunc = this._blendFunc;
228         if (dst === undefined) {
229             locBlendFunc.src = src.src;
230             locBlendFunc.dst = src.dst;
231         } else {
232             locBlendFunc.src = src;
233             locBlendFunc.dst = dst;
234         }
235         this._renderCmd.updateBlendFunc(locBlendFunc);
236     },
237 
238     _createRenderCmd: function(){
239         if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
240             return new cc.LayerColor.CanvasRenderCmd(this);
241         else
242             return new cc.LayerColor.WebGLRenderCmd(this);
243     }
244 });
245 
246 /**
247  * Creates a cc.Layer with color, width and height in Points
248  * @deprecated since v3.0 please use the new construction instead
249  * @see cc.LayerColor
250  * @param {cc.Color} color
251  * @param {Number|Null} [width=]
252  * @param {Number|Null} [height=]
253  * @return {cc.LayerColor}
254  */
255 cc.LayerColor.create = function (color, width, height) {
256     return new cc.LayerColor(color, width, height);
257 };
258 
259 //LayerColor - Getter Setter
260 (function(){
261     var proto = cc.LayerColor.prototype;
262     cc.defineGetterSetter(proto, "width", proto._getWidth, proto._setWidth);
263     cc.defineGetterSetter(proto, "height", proto._getHeight, proto._setHeight);
264 })();
265 
266 /**
267  * <p>
268  * CCLayerGradient is a subclass of cc.LayerColor that draws gradients across the background.<br/>
269  *<br/>
270  * All features from cc.LayerColor are valid, plus the following new features:<br/>
271  * <ul><li>direction</li>
272  * <li>final color</li>
273  * <li>interpolation mode</li></ul>
274  * <br/>
275  * Color is interpolated between the startColor and endColor along the given<br/>
276  * vector (starting at the origin, ending at the terminus).  If no vector is<br/>
277  * supplied, it defaults to (0, -1) -- a fade from top to bottom.<br/>
278  * <br/>
279  * If 'compressedInterpolation' is disabled, you will not see either the start or end color for<br/>
280  * non-cardinal vectors; a smooth gradient implying both end points will be still<br/>
281  * be drawn, however.<br/>
282  *<br/>
283  * If 'compressedInterpolation' is enabled (default mode) you will see both the start and end colors of the gradient.
284  * </p>
285  * @class
286  * @extends cc.LayerColor
287  *
288  * @param {cc.Color} start Starting color
289  * @param {cc.Color} end Ending color
290  * @param {cc.Point} [v=cc.p(0, -1)] A vector defines the gradient direction, default direction is from top to bottom
291  *
292  * @property {cc.Color} startColor              - Start color of the color gradient
293  * @property {cc.Color} endColor                - End color of the color gradient
294  * @property {Number}   startOpacity            - Start opacity of the color gradient
295  * @property {Number}   endOpacity              - End opacity of the color gradient
296  * @property {Number}   vector                  - Direction vector of the color gradient
297  * @property {Number}   compressedInterpolation  - Indicate whether or not the interpolation will be compressed
298  */
299 cc.LayerGradient = cc.LayerColor.extend(/** @lends cc.LayerGradient# */{
300     _endColor: null,
301     _startOpacity: 255,
302     _endOpacity: 255,
303     _alongVector: null,
304     _compressedInterpolation: false,
305     _className: "LayerGradient",
306     _colorStops: [],
307 
308     /**
309      * Constructor of cc.LayerGradient
310      * @param {cc.Color} start
311      * @param {cc.Color} end
312      * @param {cc.Point} [v=cc.p(0, -1)]
313      * @param {Array|Null} stops
314      *
315      * @example Using ColorStops argument:
316      * //startColor & endColor are for default and backward compatibility
317      * var layerGradient = new cc.LayerGradient(cc.color.RED, new cc.Color(255,0,0,0), cc.p(0, -1),
318      *                                          [{p:0, color: cc.color.RED},
319      *                                           {p:.5, color: new cc.Color(0,0,0,0)},
320      *                                           {p:1, color: cc.color.RED}]);
321      * //where p = A value between 0.0 and 1.0 that represents the position between start and end in a gradient
322      *
323      */
324     ctor: function (start, end, v, stops) {
325         cc.LayerColor.prototype.ctor.call(this);
326         this._endColor = cc.color(0, 0, 0, 255);
327         this._alongVector = cc.p(0, -1);
328         this._startOpacity = 255;
329         this._endOpacity = 255;
330 
331         if(stops && stops instanceof Array){
332             this._colorStops = stops;
333             stops.splice(0, 0, {p:0, color: start || cc.color.BLACK});
334             stops.push({p:1, color: end || cc.color.BLACK});
335         } else
336             this._colorStops = [{p:0, color: start || cc.color.BLACK}, {p:1, color: end || cc.color.BLACK}];
337 
338         cc.LayerGradient.prototype.init.call(this, start, end, v, stops);
339     },
340 
341     /**
342      * Initialization of the layer, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer
343      * @param {cc.Color} start starting color
344      * @param {cc.Color} end
345      * @param {cc.Point|Null} v
346      * @param {Array|Null} stops
347      * @return {Boolean}
348      */
349     init: function (start, end, v, stops) {
350         start = start || cc.color(0, 0, 0, 255);
351         end = end || cc.color(0, 0, 0, 255);
352         v = v || cc.p(0, -1);
353         var _t = this;
354 
355         // Initializes the CCLayer with a gradient between start and end in the direction of v.
356         var locEndColor = _t._endColor;
357         _t._startOpacity = start.a;
358 
359         locEndColor.r = end.r;
360         locEndColor.g = end.g;
361         locEndColor.b = end.b;
362         _t._endOpacity = end.a;
363 
364         _t._alongVector = v;
365         _t._compressedInterpolation = true;
366 
367         cc.LayerColor.prototype.init.call(_t, cc.color(start.r, start.g, start.b, 255));
368         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty|cc.Node._dirtyFlags.opacityDirty|cc.Node._dirtyFlags.gradientDirty);
369         return true;
370     },
371 
372     /**
373      * Sets the untransformed size of the LayerGradient.
374      * @param {cc.Size|Number} size The untransformed size of the LayerGradient or The untransformed size's width of the LayerGradient.
375      * @param {Number} [height] The untransformed size's height of the LayerGradient.
376      */
377     setContentSize: function (size, height) {
378         cc.LayerColor.prototype.setContentSize.call(this, size, height);
379         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.gradientDirty);
380     },
381 
382     _setWidth: function (width) {
383         cc.LayerColor.prototype._setWidth.call(this, width);
384         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.gradientDirty);
385     },
386     _setHeight: function (height) {
387         cc.LayerColor.prototype._setHeight.call(this, height);
388         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.gradientDirty);
389     },
390 
391     /**
392      * Returns the starting color
393      * @return {cc.Color}
394      */
395     getStartColor: function () {
396         return cc.color(this._realColor);
397     },
398 
399     /**
400      * Sets the starting color
401      * @param {cc.Color} color
402      * @example
403      * // Example
404      * myGradientLayer.setStartColor(cc.color(255,0,0));
405      * //set the starting gradient to red
406      */
407     setStartColor: function (color) {
408         this.color = color;
409         //update the color stops
410         var stops = this._colorStops;
411         if(stops && stops.length > 0){
412             var selColor = stops[0].color;
413             selColor.r = color.r;
414             selColor.g = color.g;
415             selColor.b = color.b;
416         }
417     },
418 
419     /**
420      * Sets the end gradient color
421      * @param {cc.Color} color
422      * @example
423      * // Example
424      * myGradientLayer.setEndColor(cc.color(255,0,0));
425      * //set the ending gradient to red
426      */
427     setEndColor: function (color) {
428         var locColor = this._endColor;
429         locColor.r = color.r;
430         locColor.g = color.g;
431         locColor.b = color.b;
432         //update the color stops
433         var stops = this._colorStops;
434         if(stops && stops.length > 0){
435             var selColor = stops[stops.length -1].color;
436             selColor.r = color.r;
437             selColor.g = color.g;
438             selColor.b = color.b;
439         }
440         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
441     },
442 
443     /**
444      * Returns the end color
445      * @return {cc.Color}
446      */
447     getEndColor: function () {
448         return cc.color(this._endColor);
449     },
450 
451     /**
452      * Sets starting gradient opacity
453      * @param {Number} o from 0 to 255, 0 is transparent
454      */
455     setStartOpacity: function (o) {
456         this._startOpacity = o;
457         //update the color stops
458         var stops = this._colorStops;
459         if(stops && stops.length > 0)
460             stops[0].color.a = o;
461         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
462     },
463 
464     /**
465      * Returns the starting gradient opacity
466      * @return {Number}
467      */
468     getStartOpacity: function () {
469         return this._startOpacity;
470     },
471 
472     /**
473      * Sets the end gradient opacity
474      * @param {Number} o
475      */
476     setEndOpacity: function (o) {
477         this._endOpacity = o;
478         var stops = this._colorStops;
479         if(stops && stops.length > 0)
480             stops[stops.length -1].color.a = o;
481         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
482     },
483 
484     /**
485      * Returns the end gradient opacity
486      * @return {Number}
487      */
488     getEndOpacity: function () {
489         return this._endOpacity;
490     },
491 
492     /**
493      * Sets the direction vector of the gradient
494      * @param {cc.Point} Var
495      */
496     setVector: function (Var) {
497         this._alongVector.x = Var.x;
498         this._alongVector.y = Var.y;
499         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.gradientDirty);
500     },
501 
502     /**
503      * Returns the direction vector of the gradient
504      * @return {cc.Point}
505      */
506     getVector: function () {
507         return cc.p(this._alongVector.x, this._alongVector.y);
508     },
509 
510     /**
511      * Returns whether compressed interpolation is enabled
512      * @return {Boolean}
513      */
514     isCompressedInterpolation: function () {
515         return this._compressedInterpolation;
516     },
517 
518     /**
519      * Sets whether compressed interpolation is enabled
520      * @param {Boolean} compress
521      */
522     setCompressedInterpolation: function (compress) {
523         this._compressedInterpolation = compress;
524         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.gradientDirty);
525     },
526 
527     /**
528      * Return an array of Object representing a colorStop for the gradient, if no stops was specified
529      * start & endColor will be provided as default values
530      * @example
531      * [{p: 0, color: cc.color.RED},{p: 1, color: cc.color.RED},...]
532      * @returns {Array}
533      */
534     getColorStops: function(){
535         return this._colorStops;
536     },
537     /**
538      * Set the colorStops to create the gradient using multiple point & color
539      *
540      * @param colorStops
541      *
542      * @example
543      * //startColor & endColor are for default and backward compatibility
544      * var layerGradient = new cc.LayerGradient(cc.color.RED, new cc.Color(255,0,0,0), cc.p(0, -1));
545      * layerGradient.setColorStops([{p:0, color: cc.color.RED},
546      *                              {p:.5, color: new cc.Color(0,0,0,0)},
547      *                              {p:1, color: cc.color.RED}]);
548      * //where p = A value between 0.0 and 1.0 that represents the position between start and end in a gradient
549      *
550      */
551     setColorStops: function(colorStops){
552         this._colorStops = colorStops;
553         //todo need update  the start color and end color
554         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty|cc.Node._dirtyFlags.opacityDirty|cc.Node._dirtyFlags.gradientDirty);
555     },
556 
557     _createRenderCmd: function(){
558         if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
559             return new cc.LayerGradient.CanvasRenderCmd(this);
560         else
561             return new cc.LayerGradient.WebGLRenderCmd(this);
562     }
563 });
564 
565 /**
566  * Creates a gradient layer
567  * @deprecated since v3.0, please use the new construction instead
568  * @see cc.layerGradient
569  * @param {cc.Color} start starting color
570  * @param {cc.Color} end ending color
571  * @param {cc.Point|Null} v
572  * @param {Array|NULL} stops
573  * @return {cc.LayerGradient}
574  */
575 cc.LayerGradient.create = function (start, end, v, stops) {
576     return new cc.LayerGradient(start, end, v, stops);
577 };
578 //LayerGradient - Getter Setter
579 (function(){
580     var proto = cc.LayerGradient.prototype;
581     // Extended properties
582     /** @expose */
583     proto.startColor;
584     cc.defineGetterSetter(proto, "startColor", proto.getStartColor, proto.setStartColor);
585     /** @expose */
586     proto.endColor;
587     cc.defineGetterSetter(proto, "endColor", proto.getEndColor, proto.setEndColor);
588     /** @expose */
589     proto.startOpacity;
590     cc.defineGetterSetter(proto, "startOpacity", proto.getStartOpacity, proto.setStartOpacity);
591     /** @expose */
592     proto.endOpacity;
593     cc.defineGetterSetter(proto, "endOpacity", proto.getEndOpacity, proto.setEndOpacity);
594     /** @expose */
595     proto.vector;
596     cc.defineGetterSetter(proto, "vector", proto.getVector, proto.setVector);
597     /** @expose */
598     proto.colorStops;
599     cc.defineGetterSetter(proto, "colorStops", proto.getColorStops, proto.setColorStops);
600 })();
601 
602 /**
603  * CCMultipleLayer is a CCLayer with the ability to multiplex it's children.<br/>
604  * Features:<br/>
605  *  <ul><li>- It supports one or more children</li>
606  *  <li>- Only one children will be active a time</li></ul>
607  * @class
608  * @extends cc.Layer
609  * @param {Array} layers an array of cc.Layer
610  * @example
611  * // Example
612  * var multiLayer = new cc.LayerMultiple(layer1, layer2, layer3);//any number of layers
613  */
614 cc.LayerMultiplex = cc.Layer.extend(/** @lends cc.LayerMultiplex# */{
615     _enabledLayer: 0,
616     _layers: null,
617     _className: "LayerMultiplex",
618 
619     /**
620      * Constructor of cc.LayerMultiplex
621      * @param {Array} layers an array of cc.Layer
622      */
623     ctor: function (layers) {
624         cc.Layer.prototype.ctor.call(this);
625         if (layers instanceof Array)
626             cc.LayerMultiplex.prototype.initWithLayers.call(this, layers);
627         else
628             cc.LayerMultiplex.prototype.initWithLayers.call(this, Array.prototype.slice.call(arguments));
629     },
630 
631     /**
632      * Initialization of the layer multiplex, please do not call this function by yourself, you should pass the parameters to constructor to initialize a layer multiplex
633      * @param {Array} layers an array of cc.Layer
634      * @return {Boolean}
635      */
636     initWithLayers: function (layers) {
637         if ((layers.length > 0) && (layers[layers.length - 1] == null))
638             cc.log(cc._LogInfos.LayerMultiplex_initWithLayers);
639 
640         this._layers = layers;
641         this._enabledLayer = 0;
642         this.addChild(this._layers[this._enabledLayer]);
643         return true;
644     },
645 
646     /**
647      * Switches to a certain layer indexed by n.<br/>
648      * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
649      * @param {Number} n the layer index to switch to
650      */
651     switchTo: function (n) {
652         if (n >= this._layers.length) {
653             cc.log(cc._LogInfos.LayerMultiplex_switchTo);
654             return;
655         }
656 
657         this.removeChild(this._layers[this._enabledLayer], true);
658         this._enabledLayer = n;
659         this.addChild(this._layers[n]);
660     },
661 
662     /**
663      * Release the current layer and switches to another layer indexed by n.<br/>
664      * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
665      * @param {Number} n the layer index to switch to
666      */
667     switchToAndReleaseMe: function (n) {
668         if (n >= this._layers.length) {
669             cc.log(cc._LogInfos.LayerMultiplex_switchToAndReleaseMe);
670             return;
671         }
672 
673         this.removeChild(this._layers[this._enabledLayer], true);
674 
675         //[layers replaceObjectAtIndex:_enabledLayer withObject:[NSNull null]];
676         this._layers[this._enabledLayer] = null;
677         this._enabledLayer = n;
678         this.addChild(this._layers[n]);
679     },
680 
681     /**
682      * Add a layer to the multiplex layers list
683      * @param {cc.Layer} layer
684      */
685     addLayer: function (layer) {
686         if (!layer) {
687             cc.log(cc._LogInfos.LayerMultiplex_addLayer);
688             return;
689         }
690         this._layers.push(layer);
691     }
692 });
693 
694 /**
695  * Creates a cc.LayerMultiplex with one or more layers using a variable argument list.
696  * @deprecated since v3.0, please use new construction instead
697  * @see cc.LayerMultiplex
698  * @return {cc.LayerMultiplex|Null}
699  */
700 cc.LayerMultiplex.create = function (/*Multiple Arguments*/) {
701     return new cc.LayerMultiplex(Array.prototype.slice.call(arguments));
702 };