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      * create 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) throw "Please load the resource first : " + pszFileName;
 48             this._node = this.createObject(jsonDict, null);
 49             ccs.triggerManager.parse(jsonDict["Triggers"]||[]);
 50         }while(0);
 51 
 52         return this._node;
 53     },
 54 
 55     /**
 56      *  create 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                 var 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                 }
255                 this.createObject(subDict, gb);
256                 subDict = null;
257             }
258 
259             return gb;
260         }
261 
262         return null;
263     },
264 
265 
266     nodeByTag: function (parent, tag) {
267         if (parent == null) {
268             return null;
269         }
270         var retNode = null;
271         var children = parent.getChildren();
272 
273         for (var i = 0; i < children.length; i++) {
274             var child = children[i];
275             if (child && child.getTag() == tag) {
276                 retNode = child;
277                 break;
278             }
279             else {
280                 retNode = this.nodeByTag(child, tag);
281                 if (retNode) {
282                     break;
283                 }
284             }
285         }
286         return retNode;
287     },
288 
289     getNodeByTag: function (tag) {
290         if (this._node == null) {
291             return null;
292         }
293         if (this._node.getTag() == tag) {
294             return this._node;
295         }
296         return this.nodeByTag(this._node, tag);
297     },
298 
299     /**
300      * set property
301      * @param {cc.Node} node
302      * @param {Object} dict
303      */
304     setPropertyFromJsonDict: function (node, dict) {
305         var x = (typeof dict["x"] === 'undefined')?0:dict["x"];
306         var y = (typeof dict["y"] === 'undefined')?0:dict["y"];
307         node.setPosition(x, y);
308 
309         var bVisible = Boolean((typeof dict["visible"] === 'undefined')?1:dict["visible"]);
310         node.setVisible(bVisible);
311 
312         var nTag = (typeof dict["objecttag"] === 'undefined')?-1:dict["objecttag"];
313         node.setTag(nTag);
314 
315         var nZorder = (typeof dict["zorder"] === 'undefined')?0:dict["zorder"];
316         node.setLocalZOrder(nZorder);
317 
318         var fScaleX = (typeof dict["scalex"] === 'undefined')?1:dict["scalex"];
319         var fScaleY = (typeof dict["scaley"] === 'undefined')?1:dict["scaley"];
320         node.setScaleX(fScaleX);
321         node.setScaleY(fScaleY);
322 
323         var fRotationZ = (typeof dict["rotation"] === 'undefined')?0:dict["rotation"];
324         node.setRotation(fRotationZ);
325     },
326     setTarget : function(selector,listener){
327         this._listener = listener;
328         this._selector = selector;
329     },
330     _callSelector:function(obj,subDict){
331         if(this._selector){
332             this._selector.call(this._listener,obj,subDict);
333         }
334     },
335 
336 	version: function () {
337 		return "1.2.0.0";
338 	},
339 
340     /**
341      * Clear data
342      */
343     clear: function () {
344 	    ccs.triggerManager.removeAll();
345 	    cc.audioEngine.end();
346     }
347 };