目前h5引擎正在处于研究阶段,基于Cocos2d-html5封装一个TS版的引擎库。
以前在封装UI及Scene这块的内容,UI部分涉及到加载素材,也了解到cocos能够直接使用TexturePacker合成后的plist文件及png。可是对于H5的项目来讲,减小网络请求是很重要的一步,特别是在页面初始化加载的时候。这时候在官网看到以下内容:cc.spriteFrameCache 改造说明
通俗来讲,就是在知道SpriteFrame的数据结构以后,提早将plist文件的解析(这样能够作到将多个plist文件集合到一个文件中,减小加载次数)。官网有一个作法:html
我在按照此方法的处理过程当中,发现_pkgJsonLoader中对数据结构处理的不多,只是作了数据提取部分。因此我的以为在生成.pkgJson文件时,就能够直接按照SpriteFrame数据结构来生成数据,没有必要通过两次处理。如下是官网提供的思路:html5
// SpriteFrame数据结构 { _inited : true, frames : { "a_frame_0.png" : { rect : {x : 0, y : 0, width : 1, height : 1}, rotated : false, offset : {x : 0, y : 0}, size : {width : 1, height : 1} aliases : ["a_f_0"] } }, meta : { image : "a.png" } }
// pkgJsonLoader核心代码 cc._pkgJsonLoader = { /** * @constant */ _parse : function(data){ var KEY = data instanceof Array ? this.MIN_KEY : this.KEY; var frames = {}, meta = data[KEY.meta] ? {image : data[KEY.meta][KEY.image]} : {}; var tempFrames = data[KEY.frames]; for (var frameName in tempFrames) { var f = tempFrames[frameName]; var rect = f[KEY.rect]; var size = f[KEY.size]; var offset = f[KEY.offset]; frames[frameName] = { rect : {x : rect[0], y : rect[1], width : rect[2], height : rect[3]}, size : {width : size[0], height : size[1]}, offset : {x : offset[0], y : offset[1]}, rotated : f[KEY.rotated], aliases : f[KEY.aliases] } } return {_inited : true, frames : frames, meta : meta}; }, load : function(realUrl, url, res, cb){ var self = this, locLoader = cc.loader, cache = locLoader.cache; locLoader.loadJson(realUrl, function(err, pkg){ if(err) return cb(err); var dir = cc.path.dirname(url); for (var key in pkg) { var filePath = cc.path.join(dir, key); cache[filePath] = self._parse(pkg[key]); } cb(null, true); }); } };
上面说了那么多,首先须要解决的是plist数据解析的工具,惋惜在官网上只提供了解析后的数据结构,没有解析工具。为此我在中文论坛及其它相关论坛都问了一遍,可是没有获得满意的答复。因此,决定本身造个轮子。我在npm上找到了plist包,试用了以后,发现plist能够将plist文件的数据提取出来,数据结构以下:npm
{ "frames": { "0.png": { "aliases": [ ], "spriteOffset": "{0,0}", "spriteSize": "{64,49}", "spriteSourceSize": "{64,49}", "textureRect": "{{1,55},{64,49}}", "textureRotated": false }, "1.png": { "aliases": [ ], "spriteOffset": "{0,0}", "spriteSize": "{67,52}", "spriteSourceSize": "{67,52}", "textureRect": "{{1,1},{67,52}}", "textureRotated": false } }, "metadata": { "format": 3, "pixelFormat": "RGBA8888", "premultiplyAlpha": false, "realTextureFileName": "radio.png", "size": "{69,105}", "smartupdate": "$TexturePacker:SmartUpdate:305947cb63527c2d3a81c456831d3508:0ffe9fa733c7901a53ebea001548ed6d:eed519fbbdd46973eb5ec3b717bd80b1$", "textureFileName": "radio.png" } }
其实,到了这一步,我要作的东西就很简单了。基于plist转换后的结构,提取出SprimeFrame须要的数据便可。提取结果:json
{ "_inited": true, "frames": { "0.png": { "rect": { "x": 1, "y": 55, "width": 64, "height": 49 }, "rotated": false, "offset": { "x": 0, "y": 0 }, "size": { "width": 64, "height": 49 }, "aliases": [ ] }, "1.png": { "rect": { "x": 1, "y": 1, "width": 67, "height": 52 }, "rotated": false, "offset": { "x": 0, "y": 0 }, "size": { "width": 67, "height": 52 }, "aliases": [ ] } }, "meta": { "image": "radio.png" } }
配合自定义的cc._pkgJsonLoader:缓存
cc._pkgJsonLoader = { load: function (realUrl, url, res, cb) { var self = this, locLoader = cc.loader, cache = locLoader.cache; locLoader.loadJson(realUrl, function (err, pkg) { if (err) return cb(err); var dir = cc.path.dirname(url); for (var key in pkg) { var filePath = cc.path.join(dir, key); cache[filePath] = pkg[key]; } cb(null, true); }); } }; cc.loader.register(["pkgJson"], cc._pkgJsonLoader);
其实以前提到过一部分,在此重点再说一次:网络
这部分是在和同事交流时发现一位使用了cocos好久的开发,对此过程当中到底发生了什么也不太了解。数据结构
此时,cc.loader.cache存储的仍是xml中的内容:
当咱们使用以下命令是:cc.spriteFrameCache.addSpriteFrames("xx.plist");
工具
获取plist对应的内容this
"_inited": true
属性,标记解析完成