cocos creator 热更新

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010971754/article/details/81977859

热更新的使用:官方教程:
官网热更新教程
第一步:先生成配置文件:project.manifest和version.manifest,这两个文件的作用,官网有说明
第二步:创建loading脚本,继承BaseLoading,在属性面板,设置热更新的配置文件和热更新的弹窗
热更新属性面板配置
属性面板
第三步:loading脚本中实现_fCheckUpdate方法,最后手动调用_fCheck函数,引擎自己会去对比远程和本地的版本文件
第四步:调用startHotUpate函数实现热更新,热更新结束后,游戏会重启,这样获取的就是服务器上最新的资源和脚本
updateCb这个函数中,如果版本是最新的,会进入jsb.EventAssetsManager.ALREADY_UP_TO_DATE:分支,直接读取游戏配置文件进入游戏
this._loadResCfgJson()updateCb这个函数的jsb.EventAssetsManager.UPDATE_PROGRESSION:分支,可以监听到当前下载更新的进度更新的下载进度的监听

event.getDownloadedBytes()当前下载文件的进度
event.getTotalBytes()下载文件的总大小

具体原理可以查看官方教程文档:热更新原理
这里解释下:这个指令
node version_generator.js -v 1.0.0 -u http://your-server-address/tutorial-hot-update/remote-assets/ -s native/package/ -d assets/
官方的解释是这样的:
-v 指定 Manifest 文件的主版本号。
-u 指定服务器远程包的地址,这个地址需要和最初发布版本中 Manifest 文件的远程包地址一致,否则无法检测到更新。
-s 本地原生打包版本的目录相对路径。
-d 保存 Manifest 文件的地址。
经过几代的变迁,现在一般的路径是:
-s 本地原生打包的版本:默认的构建版本路径:/build/jsb-link下
-d 就是你构建完成后,执行上面那条指令后生成最新的热更新配置文件,生成后的存放位置
所以现在一般是:
node version_generator.js -v 1.10.091 -u http://your-server-address/tutorial-hot-update/remote-assets/ -s build/jsb-link -d build/jsb-link/
version_generator.js 下载地址:version_generator.js
将生成出来的总的几个传到服务器即可

最后附上代码:

/**

     * 开始检查更新--前往检测版本差异
     */
    _fCheck () {
        // Hot update is only available in Native build
        if (! this._isNative()) {
            return;
        }
        this._storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'blackjack-remote-asset');
        console.log('Storage path for remote asset : ' + this._storagePath);
        // Setup your own version compare handler, versionA and B is versions in string
        // if the return value greater than 0, versionA is greater than B,
        // if the return value equals 0, versionA equals to B,
        // if the return value smaller than 0, versionA is smaller than B.
        this._versionCompareHandle = function (versionA, versionB) {
            console.log("JS Custom Version Compare: version A is " + versionA + ', version B is ' + versionB);
            var vA = versionA.split('.');
            var vB = versionB.split('.');
            for (var i = 0; i < vA.length; ++i) {
                var a = parseInt(vA[i]);
                var b = parseInt(vB[i] || 0);
                if (a === b) {
                    continue;
                }
                else {
                    return a - b;
                }
            }
            if (vB.length > vA.length) {
                return -1;
            }
            else {
                return 0;
            }
        };
        // Init with empty manifest url for testing custom manifest
        this._am = new jsb.AssetsManager('', this._storagePath, this._versionCompareHandle);
        if (! cc.sys.ENABLE_GC_FOR_NATIVE_OBJECTS) {
            this._am.retain();
        }
        this._am.setVerifyCallback(function (path, asset) {
            var compressed = asset.compressed;
            var expectedMD5 = asset.md5;
            var relativePath = asset.path;
            var size = asset.size;
            if (compressed) {
                return true;
            }
            else {
                return true;
            }
        });
        if (cc.sys.os === cc.sys.OS_ANDROID) {
            this._am.setMaxConcurrentTask(2);
        }
        this.checkUpdate();
    },
    updateCb (event) {
        var needRestart = false;
        var failed = false;
        Com.info('updateCb Code : ' + event.getEventCode())
        switch (event.getEventCode())
        {
            case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
                console.log("No local manifest file found, hot update skipped.");
                failed = true;
                break;
            case jsb.EventAssetsManager.UPDATE_PROGRESSION:
                var msg = event.getMessage();
                if (msg) {
                    console.log('Updated file: ' + msg);
                }
                // this._node_HotUpdate.setProgressLength(event.getDownloadedBytes(), event.getTotalBytes());
                if (this['_hotUpdateProgress']) {
                    this['_hotUpdateProgress'](event.getDownloadedBytes(), event.getTotalBytes())
                }
                break;
            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
                console.log("Fail to download manifest file, hot update skipped.");
                failed = true;
                break;
            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
                failed = true;
                Com.info('开始进入游戏1')
                console.log("Already up to date with the latest remote version.");
                //this._loadResCfgJson()
                break;
            case jsb.EventAssetsManager.UPDATE_FINISHED:
                needRestart = true;
                console.log('Update finished. ' + event.getMessage());
                break;
            case jsb.EventAssetsManager.UPDATE_FAILED:
                console.log('Update failed. ' + event.getMessage());
                break;
            case jsb.EventAssetsManager.ERROR_UPDATING:
                console.log('Asset update error: ' + event.getAssetId() + ', ' + event.getMessage());
                break;
            case jsb.EventAssetsManager.ERROR_DECOMPRESS:
                console.log(event.getMessage());
                break;
            default:
                break;
        }
        if (failed) {
            cc.eventManager.removeListener(this._updateListener);
            this._updateListener = null;
            this._updating = false;
        }
        if (needRestart) {
            cc.eventManager.removeListener(this._updateListener);
            this._updateListener = null;
            var searchPaths = jsb.fileUtils.getSearchPaths();
            var newPaths = this._am.getLocalManifest().getSearchPaths();
            console.log(JSON.stringify(newPaths));
            Array.prototype.unshift(searchPaths, newPaths); 
            cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
            jsb.fileUtils.setSearchPaths(searchPaths);
            cc.audioEngine.stopAll();
            cc.game.restart();
        }
    },
    //检查更新
    checkUpdate: function () {
        if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
            this._am.loadLocalManifest(this.manifestUrl)
            // Resolve md5 url
            /**********官方文档中的nativeUrl字段,在配置文件中是不存在的,导致会找不到本地的对比文件,坑******************* */
            // var url = this.manifestUrl.nativeUrl;
            // if (cc.loader.md5Pipe) {
            //     url = cc.loader.md5Pipe.transformURL(url);
            // }
            // this._am.loadLocalManifest(url);
            /**********官方文档中的nativeUrl字段,在配置文件中是不存在的,导致会找不到本地的对比文件,坑******************* */
        }
        if (!this._am.getLocalManifest() || !this._am.getLocalManifest().isLoaded()) {
            // this.panel.info.string = 'Failed to load local manifest ...';
            return;
        }
        /***********这个函数已经弃用,坑**************/
        // this._am.setEventCallback(this.checkCb.bind(this));
        /***********这个函数已经弃用,坑**************/
        //函数改成这个
        this._checkListener = new jsb.EventListenerAssetsManager(this._am, this.checkCb.bind(this));
        cc.eventManager.addListener(this._checkListener, 1);
        this._am.checkUpdate();
        this._updating = true;
    },
    /**
     * 开始热更新--这里开始热更新
     */
    startHotUpate: function () {
        if (this._am && !this._updating) {
            // this._am.setEventCallback(this.updateCb.bind(this));
            // if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
            //     // Resolve md5 url
            //     var url = this.manifestUrl.nativeUrl;
            //     if (cc.loader.md5Pipe) {
            //         url = cc.loader.md5Pipe.transformURL(url);
            //     }
            //     this._am.loadLocalManifest(url);
            // }
            this._updateListener = new jsb.EventListenerAssetsManager(this._am, this.updateCb.bind(this))
            cc.eventManager.addListener(this._updateListener, 1)
            if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
                this._am.loadLocalManifest(this.manifestUrl)
            }
            this._failCount = 0;
            this._am.update();
            this._updating = true;
        }
    },
    checkCb (event) {
        console.log('checkCb Code: ' + event.getEventCode());
        switch (event.getEventCode())
        {
            case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
                console.log("No local manifest file found, hot update skipped.");
                break;
            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
                console.log("Fail to download manifest file, hot update skipped.");//备注处理
                break;
            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
                Com.info('开始进入游戏2')
                console.log("Already up to date with the latest remote version.");
                //this._loadResCfgJson()
                break;
            case jsb.EventAssetsManager.NEW_VERSION_FOUND:
                //this.showUpdateTip();//这里显示更新的提示框
                break;
            default:
                return;
        }
        cc.eventManager.removeListener(this._checkListener);
        this._checkListener = null;
        this._updating = false;
    },
    retry () {
        if (!this._updating && this._canRetry) {
            this._canRetry = false;
            console.log("Retry failed Assets...");
            this._am.downloadFailedAssets();
        }
    },
    onDestroy: function () {
        if (this._updateListener) {
            this._am.setEventCallback(null);
            this._updateListener = null;
        }
    }

更多教程,it菜鸟 

猜你喜欢

转载自blog.csdn.net/u010971754/article/details/81977859
今日推荐