1 /****************************************************************************
  2  Copyright (c) 2011-2012 cocos2d-x.org
  3  Copyright (c) 2013-2014 Chukong Technologies Inc.
  4 
  5  http://www.cocos2d-x.org
  6 
  7  Permission is hereby granted, free of charge, to any person obtaining a copy
  8  of this software and associated documentation files (the "Software"), to deal
  9  in the Software without restriction, including without limitation the rights
 10  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 11  copies of the Software, and to permit persons to whom the Software is
 12  furnished to do so, subject to the following conditions:
 13 
 14  The above copyright notice and this permission notice shall be included in
 15  all copies or substantial portions of the Software.
 16 
 17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 18  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 19  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 20  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 21  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 22  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 23  THE SOFTWARE.
 24  ****************************************************************************/
 25 
 26 /**
 27  * ccs.sceneReader is the reader for Cocos Studio scene editor.
 28  * @class
 29  * @name ccs.sceneReader
 30  */
 31 ccs.sceneReader = /** @lends ccs.sceneReader# */{
 32     _baseBath:"",
 33     _listener:null,
 34     _selector:null,
 35     _node: null,
 36 
 37     /**
 38      * Creates a node with json file that exported by CocoStudio scene editor
 39      * @param pszFileName
 40      * @returns {cc.Node}
 41      */
 42     createNodeWithSceneFile: function (pszFileName) {
 43         this._node  = null;
 44         do{
 45             this._baseBath = cc.path.dirname(pszFileName);
 46             var jsonDict = cc.loader.getRes(pszFileName);
 47             if (!jsonDict)
 48                 throw "Please load the resource first : " + pszFileName;
 49             this._node = this.createObject(jsonDict, null);
 50             ccs.triggerManager.parse(jsonDict["Triggers"]||[]);
 51         }while(0);
 52         return this._node;
 53     },
 54 
 55     /**
 56      *  create UI object from data
 57      * @param {Object} inputFiles
 58      * @param {cc.Node} parenet
 59      * @returns {cc.Node}
 60      */
 61     createObject: function (inputFiles, parenet) {
 62         var className = inputFiles["classname"];
 63         if (className == "CCNode") {
 64             var gb = null;
 65             if (!parenet) {
 66                 gb = cc.Node.create();
 67             }
 68             else {
 69                 gb = cc.Node.create();
 70                 parenet.addChild(gb);
 71             }
 72 
 73             this.setPropertyFromJsonDict(gb, inputFiles);
 74 
 75             var components = inputFiles["components"];
 76             for (var i = 0; i < components.length; i++) {
 77                 var subDict = components[i];
 78                 if (!subDict) {
 79                     break;
 80                 }
 81                 className = subDict["classname"];
 82                 var comName = subDict["name"];
 83 
 84                 var fileData = subDict["fileData"];
 85                 var path = "", plistFile = "";
 86                 var resType = 0;
 87                 if (fileData != null) {
 88                     if(fileData["resourceType"] !== undefined){
 89                         resType = fileData["resourceType"]
 90                     }else{
 91                         resType =-1;
 92                     }
 93 
 94                     path = cc.path.join(this._baseBath, fileData["path"]);
 95                     plistFile = fileData["plistFile"];
 96                 }
 97 
 98                 var pathExtname = cc.path.extname(path);
 99 
100                 if (className == "CCSprite") {
101                     var sprite = null;
102 
103                     if (resType == 0) {
104                         if (pathExtname != ".png") continue;
105                         sprite = cc.Sprite.create(path);
106                     }
107                     else if (resType == 1) {
108                         if (pathExtname != ".plist") continue;
109 
110                         plistFile = cc.path.join(this._baseBath, plistFile);
111                         var pngFile = cc.path.changeExtname(plistFile, ".png");
112                         cc.spriteFrameCache.addSpriteFrames(plistFile, pngFile);
113                         sprite = cc.Sprite.create("#" + fileData["path"]);
114                     }
115                     else {
116                         continue;
117                     }
118 
119                     var render = ccs.ComRender.create(sprite, "CCSprite");
120                     if (comName != null) {
121                         render.setName(comName);
122                     }
123 
124                     gb.addComponent(render);
125                     this._callSelector(sprite, subDict);
126                 }
127                 else if (className == "CCTMXTiledMap") {
128                     var tmx = null;
129                     if (resType == 0) {
130                         if (pathExtname != ".tmx") continue;
131                         tmx = cc.TMXTiledMap.create(path);
132                     }
133                     else {
134                         continue;
135                     }
136 
137                     var render = ccs.ComRender.create(tmx, "CCTMXTiledMap");
138                     if (comName != null) {
139                         render.setName(comName);
140                     }
141                     gb.addComponent(render);
142                     this._callSelector(tmx, subDict);
143                 }
144                 else if (className == "CCParticleSystemQuad") {
145                     if (pathExtname != ".plist") continue;
146 
147                     var particle = null;
148                     if (resType == 0) {
149                         particle = cc.ParticleSystem.create(path);
150                     }
151                     else {
152                         cc.log("unknown resourcetype on CCParticleSystemQuad!");
153                         continue;
154                     }
155 
156                     particle.setPosition(0, 0);
157                     var render = ccs.ComRender.create(particle, "CCParticleSystemQuad");
158                     if (comName != null) {
159                         render.setName(comName);
160                     }
161                     gb.addComponent(render);
162                     this._callSelector(particle, subDict);
163                 }
164                 else if (className == "CCArmature") {
165                     if (resType != 0) {
166                         continue;
167                     }
168                     var jsonDict = cc.loader.getRes(path);
169                     if (!jsonDict) cc.log("Please load the resource [%s] first!", path);
170                     var armature_data = jsonDict["armature_data"];
171                     var subData = armature_data[0];
172                     var name = subData["name"];
173 
174                     ccs.armatureDataManager.addArmatureFileInfo(path);
175 
176                     var armature = ccs.Armature.create(name);
177                     var render = ccs.ComRender.create(armature, "CCArmature");
178                     if (comName != null) {
179                         render.setName(comName);
180                     }
181                     gb.addComponent(render);
182 
183                     var actionName = subDict["selectedactionname"];
184                     if (actionName && armature.getAnimation()) {
185                         armature.getAnimation().play(actionName);
186                     }
187                     jsonDict = null;
188                     subData = null;
189                     this._callSelector(armature, subDict);
190                 }
191                 else if (className == "CCComAudio") {
192                     var audio = null;
193                     if (resType == 0) {
194                         audio = ccs.ComAudio.create();
195                     }
196                     else {
197                         continue;
198                     }
199                     audio.preloadEffect(path);
200                     if (comName) {
201                         audio.setName(comName);
202                     }
203                     gb.addComponent(audio);
204                     this._callSelector(audio, subDict);
205                 }
206                 else if (className == "CCComAttribute") {
207                     var attribute = null;
208                     if (resType == 0) {
209                         attribute = ccs.ComAttribute.create();
210                         if (path != "") attribute.parse(path);
211                     }
212                     else {
213                         cc.log("unknown resourcetype on CCComAttribute!");
214                         continue;
215                     }
216                     if (comName) {
217                         attribute.setName(comName);
218                     }
219                     gb.addComponent(attribute);
220                     this._callSelector(attribute, subDict);
221                 }
222                 else if (className == "CCBackgroundAudio") {
223                     if(!pathExtname) continue;
224                     if(resType!=0) continue;
225 
226                     var audio  = ccs.ComAudio.create();
227                     audio.preloadBackgroundMusic(path);
228                     audio.setFile(path);
229                     var bLoop = Boolean(subDict["loop"] || 0);
230                     audio.setLoop(bLoop);
231                     if (comName) {
232                         audio.setName(comName);
233                     }
234                     gb.addComponent(audio);
235                     audio.playBackgroundMusic(path, bLoop);
236                     this._callSelector(audio, subDict);
237                 }
238                 else if (className == "GUIComponent") {
239                     var widget = ccs.uiReader.widgetFromJsonFile(path);
240                     var render = ccs.ComRender.create(widget, "GUIComponent");
241                     if (comName != null) {
242                         render.setName(comName);
243                     }
244                     gb.addComponent(render);
245                     this._callSelector(audio, subDict);
246                 }
247                 subDict = null;
248             }
249             var gameobjects = inputFiles["gameobjects"];
250             for (var i = 0; i < gameobjects.length; i++) {
251                 var subDict = gameobjects[i];
252                 if (!subDict)
253                     break;
254                 this.createObject(subDict, gb);
255                 subDict = null;
256             }
257             return gb;
258         }
259 
260         return null;
261     },
262 
263     _nodeByTag: function (parent, tag) {
264         if (parent == null)
265             return null;
266         var retNode = null;
267         var children = parent.getChildren();
268         for (var i = 0; i < children.length; i++) {
269             var child = children[i];
270             if (child && child.getTag() == tag) {
271                 retNode = child;
272                 break;
273             } else {
274                 retNode = this._nodeByTag(child, tag);
275                 if (retNode)
276                     break;
277             }
278         }
279         return retNode;
280     },
281 
282     /**
283      * Get a node by tag.
284      * @param {Number} tag
285      * @returns {cc.Node|null}
286      */
287     getNodeByTag: function (tag) {
288         if (this._node == null)
289             return null;
290         if (this._node.getTag() == tag)
291             return this._node;
292         return this._nodeByTag(this._node, tag);
293     },
294 
295     /**
296      * Sets properties from json dictionary.
297      * @param {cc.Node} node
298      * @param {Object} dict
299      */
300     setPropertyFromJsonDict: function (node, dict) {
301         var x = (cc.isUndefined(dict["x"]))?0:dict["x"];
302         var y = (cc.isUndefined(dict["y"]))?0:dict["y"];
303         node.setPosition(x, y);
304 
305         var bVisible = Boolean((cc.isUndefined(dict["visible"]))?1:dict["visible"]);
306         node.setVisible(bVisible);
307 
308         var nTag = (cc.isUndefined(dict["objecttag"]))?-1:dict["objecttag"];
309         node.setTag(nTag);
310 
311         var nZorder = (cc.isUndefined(dict["zorder"]))?0:dict["zorder"];
312         node.setLocalZOrder(nZorder);
313 
314         var fScaleX = (cc.isUndefined(dict["scalex"]))?1:dict["scalex"];
315         var fScaleY = (cc.isUndefined(dict["scaley"]))?1:dict["scaley"];
316         node.setScaleX(fScaleX);
317         node.setScaleY(fScaleY);
318 
319         var fRotationZ = (cc.isUndefined(dict["rotation"]))?0:dict["rotation"];
320         node.setRotation(fRotationZ);
321     },
322 
323     /**
324      * Sets the listener to reader.
325      * @param {function} selector
326      * @param {Object} listener the target object.
327      */
328     setTarget : function(selector,listener){
329         this._listener = listener;
330         this._selector = selector;
331     },
332 
333     _callSelector:function(obj,subDict){
334         if(this._selector)
335             this._selector.call(this._listener,obj,subDict);
336     },
337 
338     /**
339      * Returns the version of ccs.SceneReader.
340      * @returns {string}
341      */
342 	version: function () {
343 		return "1.2.0.0";
344 	},
345 
346     /**
347      * Clear all triggers and stops all sounds.
348      */
349     clear: function () {
350 	    ccs.triggerManager.removeAll();
351 	    cc.audioEngine.end();
352     }
353 };