1 /****************************************************************************
  2  Copyright (c) 2010-2012 cocos2d-x.org
  3 
  4  http://www.cocos2d-x.org
  5 
  6  Permission is hereby granted, free of charge, to any person obtaining a copy
  7  of this software and associated documentation files (the "Software"), to deal
  8  in the Software without restriction, including without limitation the rights
  9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10  copies of the Software, and to permit persons to whom the Software is
 11  furnished to do so, subject to the following conditions:
 12 
 13  The above copyright notice and this permission notice shall be included in
 14  all copies or substantial portions of the Software.
 15 
 16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22  THE SOFTWARE.
 23  ****************************************************************************/
 24 
 25 /**
 26  * Base class for ccs.SceneReader
 27  * @class
 28  * @extends ccs.Class
 29  */
 30 ccs.SceneReader = ccs.Class.extend(/** @lends ccs.SceneReader# */{
 31     _baseBath:"",
 32     _listener:null,
 33     _selector:null,
 34     _node: null,
 35     ctor: function () {
 36         this._instance = null;
 37         this._baseBath = "";
 38         this._listener = null;
 39         this._selector = null;
 40     },
 41     /**
 42      * create node with json file that exported by cocostudio scene editor
 43      * @param pszFileName
 44      * @returns {cc.Node}
 45      */
 46     createNodeWithSceneFile: function (pszFileName) {
 47         var data = 0;
 48         do {
 49             var pos = pszFileName.lastIndexOf("/");
 50             if(pos>-1){
 51                 this._baseBath =pszFileName.substr(0,pos+1);
 52             }
 53             data = cc.FileUtils.getInstance().getTextFileData(pszFileName);
 54 
 55             if (!data)
 56                 break;
 57 
 58             var jsonDict = JSON.parse(data);
 59             this._node = this.createObject(jsonDict, null);
 60             ccs.TriggerMng.getInstance().parse(jsonDict["Triggers"]||[]);
 61         } while (0);
 62         this._baseBath = "";
 63         return this._node;
 64     },
 65 
 66     /**
 67      *  create object from data
 68      * @param {Object} inputFiles
 69      * @param {cc.Node} parenet
 70      * @returns {cc.Node}
 71      */
 72     createObject: function (inputFiles, parenet) {
 73         var className = inputFiles["classname"];
 74         if (className == "CCNode") {
 75             var gb = null;
 76             if (!parenet) {
 77                 gb = cc.Node.create();
 78             }
 79             else {
 80                 gb = cc.Node.create();
 81                 parenet.addChild(gb);
 82             }
 83 
 84             this.setPropertyFromJsonDict(gb, inputFiles);
 85 
 86             var components = inputFiles["components"];
 87             for (var i = 0; i < components.length; i++) {
 88                 var subDict = components[i];
 89                 if (!subDict) {
 90                     break;
 91                 }
 92                 var className = subDict["classname"];
 93                 var comName = subDict["name"];
 94 
 95                 var fileData = subDict["fileData"];
 96                 var path = "",fullPath = "",plistFile = "",fullPlistFile = "";
 97                 var resType = 0;
 98                 path +=this._baseBath;
 99                 if (fileData != null) {
100                     if(fileData["resourceType"] !== undefined){
101                         resType = fileData["resourceType"]
102                     }else{
103                         resType =-1;
104                     }
105 
106                     path += fileData["path"];
107                     plistFile += fileData["plistFile"];
108 
109                     fullPath = cc.FileUtils.getInstance().fullPathForFilename(path);
110                     fullPlistFile = cc.FileUtils.getInstance().fullPathForFilename(plistFile);
111                 }
112 
113                 if (className == "CCSprite") {
114                     var sprite = null;
115 
116                     if (resType == 0) {
117                         var startPos = path.lastIndexOf(".png");
118                         if (startPos <= -1) {
119                             continue;
120                         }
121                         sprite = cc.Sprite.create(path);
122                     }
123                     else if (resType == 1) {
124                         var startPos = plistFile.lastIndexOf(".plist");
125                         if (startPos <= -1) {
126                             continue;
127                         }
128                         var startPos = plistFile.lastIndexOf(".", plistFile.length);
129                         var pngFile = plistFile.substr(0, startPos);
130                         pngFile = pngFile + ".png";
131 
132                         plistFile = this._baseBath + plistFile;
133                         pngFile = this._baseBath + pngFile;
134                         cc.SpriteFrameCache.getInstance().addSpriteFrames(plistFile, pngFile);
135                         sprite = cc.Sprite.createWithSpriteFrameName(fileData["path"]);
136                     }
137                     else {
138                         continue;
139                     }
140 
141                     var render = ccs.ComRender.create(sprite, "CCSprite");
142                     if (comName != null) {
143                         render.setName(comName);
144                     }
145 
146                     gb.addComponent(render);
147                     this._callSelector(sprite, subDict);
148                 }
149                 else if (className == "CCTMXTiledMap") {
150                     var tmx = null;
151                     if (resType == 0) {
152                         var startPos = path.lastIndexOf(".tmx");
153                         if (startPos <= -1) {
154                             continue;
155                         }
156                         tmx = cc.TMXTiledMap.create(path);
157                     }
158                     else {
159                         continue;
160                     }
161 
162                     var render = ccs.ComRender.create(tmx, "CCTMXTiledMap");
163                     if (comName != null) {
164                         render.setName(comName);
165                     }
166                     gb.addComponent(render);
167                     this._callSelector(tmx, subDict);
168                 }
169                 else if (className == "CCParticleSystemQuad") {
170                     var startPos = path.lastIndexOf(".plist");
171                     if (startPos <= -1) {
172                         continue;
173                     }
174 
175                     var particle = null;
176                     if (resType == 0) {
177                         particle = cc.ParticleSystem.create(path);
178                     }
179                     else {
180                         cc.log("unknown resourcetype on CCParticleSystemQuad!");
181                     }
182 
183                     particle.setPosition(0, 0);
184                     var render = ccs.ComRender.create(particle, "CCParticleSystemQuad");
185                     if (comName != null) {
186                         render.setName(comName);
187                     }
188                     gb.addComponent(render);
189                     this._callSelector(particle, subDict);
190                 }
191                 else if (className == "CCArmature") {
192                     if (resType != 0) {
193                         continue;
194                     }
195                     var reDir = path;
196                     var file_path = "";
197                     var pos = reDir.lastIndexOf('/');
198                     if (pos != -1) {
199                         file_path = reDir.substr(0, pos + 1);
200                     }
201                     var des = cc.FileUtils.getInstance().getTextFileData(path);
202                     if (!des) {
203                         cc.log("read json file[%s] error!\n", path);
204                         continue;
205                     }
206                     var jsonDict = JSON.parse(des);
207                     var armature_data = jsonDict["armature_data"];
208                     var subData = armature_data[0];
209                     var name = subData["name"];
210 
211                     ccs.ArmatureDataManager.getInstance().addArmatureFileInfo(path);
212 
213                     var armature = ccs.Armature.create(name);
214                     var render = ccs.ComRender.create(armature, "CCArmature");
215                     if (comName != null) {
216                         render.setName(comName);
217                     }
218                     gb.addComponent(render);
219 
220                     var actionName = subDict["selectedactionname"];
221                     if (actionName && armature.getAnimation()) {
222                         armature.getAnimation().play(actionName);
223                     }
224                     jsonDict = null;
225                     subData = null;
226                     des = null;
227                     this._callSelector(armature, subDict);
228                 }
229                 else if (className == "CCComAudio") {
230                     var audio = null;
231                     if (resType == 0) {
232                         audio = ccs.ComAudio.create();
233                     }
234                     else {
235                         continue;
236                     }
237                     audio.preloadEffect(path);
238                     if (comName) {
239                         audio.setName(comName);
240                     }
241                     gb.addComponent(audio);
242                     this._callSelector(audio, subDict);
243                 }
244                 else if (className == "CCComAttribute") {
245                     var attribute = null;
246                     if (resType == 0) {
247                         attribute = ccs.ComAttribute.create();
248                         if (this._baseBath != path) {
249                             attribute.parse(path);
250                         }
251                     }
252                     else {
253                         cc.log("unknown resourcetype on CCComAttribute!");
254                         continue;
255                     }
256                     if (comName) {
257                         attribute.setName(comName);
258                     }
259                     gb.addComponent(attribute);
260                     this._callSelector(attribute, subDict);
261                 }
262                 else if (className == "CCBackgroundAudio") {
263                     var audio = null;
264                     if (resType == 0) {
265                         audio = ccs.ComAudio.create();
266                     }
267                     else {
268                         continue;
269                     }
270                     audio.preloadBackgroundMusic(path);
271                     audio.setFile(path);
272                     var bLoop = Boolean(subDict["loop"] || 0);
273                     audio.setLoop(bLoop);
274                     if (comName) {
275                         audio.setName(comName);
276                     }
277                     gb.addComponent(audio);
278                     audio.playBackgroundMusic(path, bLoop);
279                     this._callSelector(audio, subDict);
280                 }
281                 else if (className == "GUIComponent") {
282                     var pLayer = ccs.UILayer.create();
283                     pLayer.scheduleUpdate();
284                     var widget = ccs.GUIReader.getInstance().widgetFromJsonFile(path);
285                     pLayer.addWidget(widget);
286                     var render = ccs.ComRender.create(pLayer, "GUIComponent");
287                     if (comName != null) {
288                         render.setName(comName);
289                     }
290                     gb.addComponent(render);
291                     this._callSelector(audio, subDict);
292                 }
293                 subDict = null;
294             }
295             var gameobjects = inputFiles["gameobjects"];
296             for (var i = 0; i < gameobjects.length; i++) {
297                 var subDict = gameobjects[i];
298                 if (!subDict) {
299                     break;
300                 }
301                 this.createObject(subDict, gb);
302                 subDict = null;
303             }
304 
305             return gb;
306         }
307 
308         return null;
309     },
310 
311 
312     nodeByTag: function (parent, tag) {
313         if (parent == null) {
314             return null;
315         }
316         var retNode = null;
317         var children = parent.getChildren();
318 
319         for (var i = 0; i < children.length; i++) {
320             var child = children[i];
321             if (child && child.getTag() == tag) {
322                 retNode = child;
323                 break;
324             }
325             else {
326                 retNode = this.nodeByTag(child, tag);
327                 if (retNode) {
328                     break;
329                 }
330             }
331         }
332         return retNode;
333     },
334 
335     getNodeByTag: function (tag) {
336         if (this._node == null) {
337             return null;
338         }
339         if (this._node.getTag() == tag) {
340             return this._node;
341         }
342         return this.nodeByTag(this._node, tag);
343     },
344 
345     /**
346      * set property
347      * @param {cc.Node} node
348      * @param {Object} dict
349      */
350     setPropertyFromJsonDict: function (node, dict) {
351         var x = (typeof dict["x"] === 'undefined')?0:dict["x"];
352         var y = (typeof dict["y"] === 'undefined')?0:dict["y"];
353         node.setPosition(cc.p(x, y));
354 
355         var bVisible = Boolean((typeof dict["visible"] === 'undefined')?1:dict["visible"]);
356         node.setVisible(bVisible);
357 
358         var nTag = (typeof dict["objecttag"] === 'undefined')?-1:dict["objecttag"];
359         node.setTag(nTag);
360 
361         var nZorder = (typeof dict["zorder"] === 'undefined')?0:dict["zorder"];
362         node.setZOrder(nZorder);
363 
364         var fScaleX = (typeof dict["scalex"] === 'undefined')?1:dict["scalex"];
365         var fScaleY = (typeof dict["scaley"] === 'undefined')?1:dict["scaley"];
366         node.setScaleX(fScaleX);
367         node.setScaleY(fScaleY);
368 
369         var fRotationZ = (typeof dict["rotation"] === 'undefined')?0:dict["rotation"];
370         node.setRotation(fRotationZ);
371     },
372     setTarget : function(selector,listener){
373         this._listener = listener;
374         this._selector = selector;
375     },
376     _callSelector:function(obj,subDict){
377         if(this._selector){
378             this._selector.call(this._listener,obj,subDict);
379         }
380     },
381     /**
382      * purge instance
383      */
384     purge: function () {
385         cc.log("deprecated. purge is a static class now. Use 'ccs.SceneReader.purge()' instead.");
386         this._instance = null;
387     }
388 });
389 ccs.SceneReader._instance = null;
390 /**
391  * get a singleton SceneReader
392  * @function
393  * @return {ccs.SceneReader}
394  */
395 ccs.SceneReader.getInstance = function () {
396     if (!this._instance) {
397         this._instance = new ccs.SceneReader();
398     }
399     return this._instance;
400 };
401 /**
402  * purge instance
403  */
404 ccs.SceneReader.purge = function () {
405     ccs.TriggerMng.getInstance().destroyInstance();
406     cc.AudioEngine.end();
407     this._instance = null;
408 };
409 ccs.SceneReader.sceneReaderVersion = function () {
410     return "1.2.0.0";
411 };
412