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