cocos2d js cc.ParticleSystem加载plist文件失败缘由分析

使用cocos2d-js作项目,遇到cc.ParticleSystem加载plist文件失败,通常是如下几个缘由形成的:通常都是发生在网页调试,vs的win32平台和手机原平生台运行正常,问题就定位到cocos-html的js文件中。通常都是发生在只有plist文件,没有plist文件对应的png文件的时候(plist粒子文件是用cocos studio生成的)。html

  1. 首先plist文件须要预加载,不然在initWithFile时,获取的plist文件信息为空。
    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]];
            },

     

  2. 若是plist粒子文件中不包含png的base64编码信息,那么须要将文件用到的png文件也添加到预加载里面去,最好是在plist以前预加载。
  3. 若是plist粒子文件中包含了png的base64编码信息,那么实际上是能够不用把plist用到的png文件添加进来的,一般建立粒子后在网页端不显示就是这种状况下发生的。
    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

  1. 将plist文件对应的png文件也添加到预加载中;
  2. 修改js代码。

如今用cocos-js的人少了,这篇博客估计也没多少人看吧。debug