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  * <p>cc.AtlasNode is a subclass of cc.Node, it knows how to render a TextureAtlas object. </p>
 29  *
 30  * <p>If you are going to render a TextureAtlas consider subclassing cc.AtlasNode (or a subclass of cc.AtlasNode)</p>
 31  *
 32  * <p>All features from cc.Node are valid</p>
 33  *
 34  * <p>You can create a cc.AtlasNode with an Atlas file, the width, the height of each item and the quantity of items to render</p>
 35  *
 36  * @class
 37  * @extends cc.Node
 38  *
 39  * @param {String} tile
 40  * @param {Number} tileWidth
 41  * @param {Number} tileHeight
 42  * @param {Number} itemsToRender
 43  * @example
 44  * var node = new cc.AtlasNode("pathOfTile", 16, 16, 1);
 45  *
 46  * @property {cc.Texture2D}     texture         - Current used texture
 47  * @property {cc.TextureAtlas}  textureAtlas    - Texture atlas for cc.AtlasNode
 48  * @property {Number}           quadsToDraw     - Number of quads to draw
 49  */
 50 cc.AtlasNode = cc.Node.extend(/** @lends cc.AtlasNode# */{
 51     textureAtlas: null,
 52     quadsToDraw: 0,
 53 
 54     //! chars per row
 55     _itemsPerRow: 0,
 56     //! chars per column
 57     _itemsPerColumn: 0,
 58     //! width of each char
 59     _itemWidth: 0,
 60     //! height of each char
 61     _itemHeight: 0,
 62 
 63     // protocol variables
 64     _opacityModifyRGB: false,
 65     _blendFunc: null,
 66 
 67     // This variable is only used for CCLabelAtlas FPS display. So plz don't modify its value.
 68     _ignoreContentScaleFactor: false,
 69     _className: "AtlasNode",
 70 
 71     _textureForCanvas: null,
 72 
 73     /**
 74      * <p>Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.</p>
 75      * @param {String} tile
 76      * @param {Number} tileWidth
 77      * @param {Number} tileHeight
 78      * @param {Number} itemsToRender
 79      */
 80     ctor: function (tile, tileWidth, tileHeight, itemsToRender) {
 81         cc.Node.prototype.ctor.call(this);
 82         this._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
 83         this._ignoreContentScaleFactor = false;
 84         itemsToRender !== undefined && this.initWithTileFile(tile, tileWidth, tileHeight, itemsToRender);
 85     },
 86 
 87     _createRenderCmd: function(){
 88         if(cc._renderType === cc._RENDER_TYPE_CANVAS)
 89             this._renderCmd = new cc.AtlasNode.CanvasRenderCmd(this);
 90         else
 91             this._renderCmd = new cc.AtlasNode.WebGLRenderCmd(this);
 92     },
 93 
 94     /**
 95      * Updates the Atlas (indexed vertex array).
 96      * Empty implementation, shall be overridden in subclasses
 97      * @function
 98      */
 99     updateAtlasValues: function () {
100         cc.log(cc._LogInfos.AtlasNode_updateAtlasValues);
101     },
102 
103     /**
104      * Get color value of the atlas node
105      * @function
106      * @return {cc.Color}
107      */
108     getColor: function () {
109         if (this._opacityModifyRGB)
110             return this._renderCmd._colorUnmodified;
111         return cc.Node.prototype.getColor.call(this);
112     },
113 
114     /**
115      * Set whether color should be changed with the opacity value,
116      * if true, node color will change while opacity changes.
117      * @function
118      * @param {Boolean} value
119      */
120     setOpacityModifyRGB: function (value) {
121         var oldColor = this.color;
122         this._opacityModifyRGB = value;
123         this.setColor(oldColor);
124     },
125 
126     /**
127      * Get whether color should be changed with the opacity value
128      * @function
129      * @return {Boolean}
130      */
131     isOpacityModifyRGB: function () {
132         return this._opacityModifyRGB;
133     },
134 
135     /**
136      * Get node's blend function
137      * @function
138      * @return {cc.BlendFunc}
139      */
140     getBlendFunc: function () {
141         return this._blendFunc;
142     },
143 
144     /**
145      * Set node's blend function
146      * This function accept either cc.BlendFunc object or source value and destination value
147      * @function
148      * @param {Number | cc.BlendFunc} src
149      * @param {Number} dst
150      */
151     setBlendFunc: function (src, dst) {
152         if (dst === undefined)
153             this._blendFunc = src;
154         else
155             this._blendFunc = {src: src, dst: dst};
156     },
157 
158     /**
159      * Set the atlas texture
160      * @function
161      * @param {cc.TextureAtlas} value The texture
162      */
163     setTextureAtlas: function (value) {
164         this.textureAtlas = value;
165     },
166 
167     /**
168      * Get the atlas texture
169      * @function
170      * @return {cc.TextureAtlas}
171      */
172     getTextureAtlas: function () {
173         return this.textureAtlas;
174     },
175 
176     /**
177      * Get the number of quads to be rendered
178      * @function
179      * @return {Number}
180      */
181     getQuadsToDraw: function () {
182         return this.quadsToDraw;
183     },
184 
185     /**
186      * Set the number of quads to be rendered
187      * @function
188      * @param {Number} quadsToDraw
189      */
190     setQuadsToDraw: function (quadsToDraw) {
191         this.quadsToDraw = quadsToDraw;
192     },
193 
194     /**
195      * Initializes an cc.AtlasNode object with an atlas texture file name, the width, the height of each tile and the quantity of tiles to render
196      * @function
197      * @param {String} tile             The atlas texture file name
198      * @param {Number} tileWidth        The width of each tile
199      * @param {Number} tileHeight       The height of each tile
200      * @param {Number} itemsToRender    The quantity of tiles to be rendered
201      * @return {Boolean}
202      */
203     initWithTileFile: function (tile, tileWidth, tileHeight, itemsToRender) {
204         if (!tile)
205             throw "cc.AtlasNode.initWithTileFile(): title should not be null";
206         var texture = cc.textureCache.addImage(tile);
207         return this.initWithTexture(texture, tileWidth, tileHeight, itemsToRender);
208     },
209 
210     /**
211      * Initializes an CCAtlasNode with an atlas texture, the width, the height of each tile and the quantity of tiles to render
212      * @function
213      * @param {cc.Texture2D} texture    The atlas texture
214      * @param {Number} tileWidth        The width of each tile
215      * @param {Number} tileHeight       The height of each tile
216      * @param {Number} itemsToRender    The quantity of tiles to be rendered
217      * @return {Boolean}
218      */
219     initWithTexture: function(texture, tileWidth, tileHeight, itemsToRender){
220         return this._renderCmd.initWithTexture(texture, tileWidth, tileHeight, itemsToRender);
221     },
222 
223     /**
224      * Set node's color
225      * @function
226      * @param {cc.Color} color Color object created with cc.color(r, g, b).
227      */
228     setColor: function(color){
229         this._renderCmd.setColor(color);
230     },
231 
232     /**
233      * Set node's opacity
234      * @function
235      * @param {Number} opacity The opacity value
236      */
237     setOpacity: function (opacity) {
238         this._renderCmd.setOpacity(opacity);
239     },
240 
241     /**
242      * Get the current texture
243      * @function
244      * @return {cc.Texture2D}
245      */
246     getTexture: function(){
247         return this._renderCmd.getTexture();
248     },
249 
250     /**
251      * Replace the current texture with a new one
252      * @function
253      * @param {cc.Texture2D} texture    The new texture
254      */
255     setTexture: function(texture){
256         this._renderCmd.setTexture(texture);
257     },
258 
259     _setIgnoreContentScaleFactor: function (ignoreContentScaleFactor) {
260         this._ignoreContentScaleFactor = ignoreContentScaleFactor;
261     }
262 });
263 
264 
265 var _p = cc.AtlasNode.prototype;
266 // Override properties
267 cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity);
268 cc.defineGetterSetter(_p, "color", _p.getColor, _p.setColor);
269 
270 // Extended properties
271 /** @expose */
272 _p.texture;
273 cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture);
274 /** @expose */
275 _p.textureAtlas;
276 /** @expose */
277 _p.quadsToDraw;
278 
279 cc.EventHelper.prototype.apply(_p);
280 
281 /**
282  * Creates a cc.AtlasNode with an Atlas file the width and height of each item and the quantity of items to render
283  * @deprecated since v3.0, please use new construction instead
284  * @function
285  * @static
286  * @param {String} tile
287  * @param {Number} tileWidth
288  * @param {Number} tileHeight
289  * @param {Number} itemsToRender
290  * @return {cc.AtlasNode}
291  */
292 cc.AtlasNode.create = function (tile, tileWidth, tileHeight, itemsToRender) {
293     return new cc.AtlasNode(tile, tileWidth, tileHeight, itemsToRender);
294 };