cocos2d js cc.ParticleSystem加载plist文件失败原因分析

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

  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中获取文件信息的。

            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报错:

    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方法里出现了如下代码:

    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创建出粒子了。

 

写在最后:

       其实就两种方法:

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

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

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值