使用cocos2d-js作项目,遇到cc.ParticleSystem加载plist文件失败,通常是如下几个缘由形成的:通常都是发生在网页调试,vs的win32平台和手机原平生台运行正常,问题就定位到cocos-html的js文件中。通常都是发生在只有plist文件,没有plist文件对应的png文件的时候(plist粒子文件是用cocos studio生成的)。html
initWithFile: function (plistFile) { this._plistFile = plistFile; var dict = cc.loader.getRes(plistFile); if (!dict) { cc.log("cc.ParticleSystem.initWithFile(): Particles: file not found"); return false; } // XXX compute path from a path, should define a function somewhere to do it return this.initWithDictionary(dict, ""); },
由于cc.loader.getRes()是从cc.cahe中获取文件信息的。canvas
getRes: function (url) { return this.cache[url] || this.cache[_aliases[url]]; },
if (tex) { this.setTexture(tex); } else { var textureData = locValueForKey("textureImageData", dictionary); if (!textureData || textureData.length === 0) { tex = cc.textureCache.addImage(imgPath); if (!tex) return false; this.setTexture(tex); } else { buffer = cc.unzipBase64AsArray(textureData, 1); if (!buffer) { cc.log("cc.ParticleSystem: error decoding or ungzipping textureImageData"); return false; } var imageFormat = cc.getImageFormatByData(buffer); if (imageFormat !== cc.FMT_TIFF && imageFormat !== cc.FMT_PNG) { cc.log("cc.ParticleSystem: unknown image format with Data"); return false; } var canvasObj = document.createElement("canvas"); if (imageFormat === cc.FMT_PNG) { var myPngObj = new cc.PNGReader(buffer); myPngObj.render(canvasObj); } else { var myTIFFObj = cc.tiffReader; myTIFFObj.parseTIFF(buffer, canvasObj); } cc.textureCache.cacheImage(imgPath, canvasObj); var addTexture = cc.textureCache.getTextureForKey(imgPath); if (!addTexture) cc.log("cc.ParticleSystem.initWithDictionary() : error loading the texture"); this.setTexture(addTexture); } }
经过cc.ParticleSystem类的initWithDictionary方法能够看出来,将图片添加到预加载后,tex就不是从base64编码中获取的了,而是直接读取图片文件的。因此问题出如今base64解码方法里,断点后的结果显示是cc.unzipBase64AsArray的cc.unzipBase64报错:app
cc.unzipBase64 = function () { var tmpInput = cc.Codec.Base64.decode.apply(cc.Codec.Base64, arguments); return cc.Codec.GZip.gunzip.apply(cc.Codec.GZip, [tmpInput]); };
cc.Codec.GZip.gunzip = function (string) { if (string.constructor === Array) { } else if (string.constructor === String) { } var gzip = new cc.Codec.GZip(string); return gzip.gunzip()[0][0]; };
cc.Codec.GZip.prototype.gunzip = function () { this.outputArr = []; //convertToByteArray(input); //if (this.debug) alert(this.data); this.nextFile(); return this.unzipped; };
而cc.Codec.GZip.prototype.nextFile方法里出现了以下代码:this
if (tmp[0] === 0x78 && tmp[1] === 0xda) { //GZIP if (tmp[0] === 0x1f && tmp[1] === 0x8b) { //GZIP if (tmp[0] === 0x50 && tmp[1] === 0x4b) { //ZIP
0x1f,0x8b等等是用来判断压缩标准的,问题就出在这里:读取的plist文件里的base64解码后解压时读取到头是0x78和0x9c,原来的代码里没有这个选择语句,解决办法就是添加一个选择语句,判断条件为0x78和0x9c,解压逻辑复制0x78和0xda的就行了。这样网页调试就能够根据plist建立出粒子了。编码
写在最后:url
其实就两种方法:prototype
如今用cocos-js的人少了,这篇博客估计也没多少人看吧。debug