CocosCreator热更新

本文详细描述了在CocosCreator2.4.12环境中配置Node.js环境以及热更新的步骤,包括初始化AssetsManager、设置验证回调、版本比较和检查更新、下载与更新过程中的事件处理。
摘要由CSDN通过智能技术生成

环境说明:

  1. CocosCreator2.4.12
  2. Windows/Mac环境下安卓需要配置环境
  3. 安装nodejs环境用于生成版本更新文件
  4. Cocos官网下载CocosDashBoard

热更新流程图:

1、创建CocosCreator热更新测试项目工程

2、关键代码说明:

初始化AssetsManager

protected onLoad(): void {

    this._stotagePath = this.getCacheRootPath();
    console.log(TAG, `远程版本缓存路径:${this._stotagePath}`);
    this._hallAssetsMgr = new jsb.AssetsManager('', this._stotagePath, this.versionCompareHandle);
    this._hallAssetsMgr.setVerifyCallback(this.setVerifyCallback.bind(this));

}

setVerifyCallback(path, asset) {

    let compressed = asset.compressed;
    let expectedMD5 = asset.md5;
    let relativePath = asset.path;
    let size = asset.size;
    console.log("assetPath", path)
    console.log("assetSize:", size);
    if (compressed) {
        this.toolTipslabel.string = "检查压缩 : " + relativePath;
        return true;
    } else {
        this.toolTipslabel.string = "检查压缩 : " + relativePath + ' (' + expectedMD5 + ')';
        return true;
    }
}

versionCompareHandle(versionA: string, versionB: string) {
    console.log(`当前版本 :  ${versionA} , 远程版本 : ${versionB}`);
    let vA = versionA.split('.');
    let vB = versionB.split('.');
    for (let i = 0; i < vA.length && i < vB.length; ++i) {
        let a = parseInt(vA[i]);
        let b = parseInt(vB[i]);
        if (a === b) {
            continue;
        }
        else {
            return -1;
        }
    }
    if (vB.length > vA.length) {
        return -1;
    }
    return 0;
}

检查是否可进行更新

public doCheckUpdate() {
    if (this._updating) {
        return;
    }
    let url = this.hallMainifestUrl.nativeUrl;
    console.log(TAG, `<checkUpdate> 原包版本信息url: ${this.hallMainifestUrl.nativeUrl}`);
    if (this._hallAssetsMgr.getState() === jsb.AssetsManager.State.UNINITED) {
        if (cc.loader.md5Pipe) {
            url = cc.loader.md5Pipe.transformURL(url);
        }
        this._hallAssetsMgr.loadLocalManifest(url);
    }
    if (!this._hallAssetsMgr.getLocalManifest() || !this._hallAssetsMgr.getLocalManifest().isLoaded()) {
        this.toolTipslabel.string = '加载本地manifest文件失败';
        return;
    }
    this._hallAssetsMgr.setEventCallback(this.checkUpdateCallback.bind(this));
    this._hallAssetsMgr.checkUpdate();
    this._updating = true;
}

执行热更新操作

public doHotUpdate() {
    if (this._hallAssetsMgr && !this._updating) {
        this._hallAssetsMgr.setEventCallback(this.updateCallback.bind(this));
        if (this._hallAssetsMgr.getState() === jsb.AssetsManager.State.UNINITED) {
            let url = this.hallMainifestUrl.nativeUrl;
            if (cc.loader.md5Pipe) {
                url = cc.loader.md5Pipe.transformURL(url);
            }
            this._hallAssetsMgr.loadLocalManifest(url);
        }
        this._hallAssetsMgr.update();
        this._updating = true;
    }
}

代码详细

/**
 * @Description: 检查是否可进行更新
 * @Date: 2024-01-16 10:58:47
 * @Author: LeeSir add
 * @return {*}
 */
public doCheckUpdate() {
    if (this._updating) {
        return;
    }
    let url = this.hallMainifestUrl.nativeUrl;
    console.log(TAG, `<checkUpdate> 原包版本信息url: ${this.hallMainifestUrl.nativeUrl}`);
    if (this._hallAssetsMgr.getState() === jsb.AssetsManager.State.UNINITED) {
        if (cc.loader.md5Pipe) {
            url = cc.loader.md5Pipe.transformURL(url);
        }
        this._hallAssetsMgr.loadLocalManifest(url);
    }
    if (!this._hallAssetsMgr.getLocalManifest() || !this._hallAssetsMgr.getLocalManifest().isLoaded()) {
        this.toolTipslabel.string = '加载本地manifest文件失败';
        return;
    }
    this._hallAssetsMgr.setEventCallback(this.checkUpdateCallback.bind(this));
    this._hallAssetsMgr.checkUpdate();
    this._updating = true;
}

/**
 * @Description: 检查是否可更新回调函数
 * @Date: 2024-01-16 10:59:16
 * @Author: LeeSir add
 * @param {*} event
 * @return {*}
 */
private checkUpdateCallback(event) {
    console.log(TAG, `Event Code: ${event.getEventCode()}`);
    switch (event.getEventCode()) {
        case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
            this.toolTipslabel.string = "没有本地manifest文件,跳过热更.";
            console.log(TAG, `<checkUpdateCallback> 没有本地manifest文件,跳过热更. `);
            this.hotUpdateFinishStatusFunc(false);
            break;
        case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
        case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
            this.toolTipslabel.string = "下载远程manifest文件失败,跳过热更.";
            console.log(TAG, `<checkUpdateCallback> 下载远程manifest文件失败,跳过热更. `);
            this.hotUpdateFinishStatusFunc(false);
            break;
        case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
            this.toolTipslabel.string = "已经更新到远程最新版本.";
            console.log(TAG, `<checkUpdateCallback> 已经更新到远程最新版本. `);
            this.hotUpdateFinishStatusFunc(false);
            break;
        case jsb.EventAssetsManager.NEW_VERSION_FOUND:
            this.toolTipslabel.string = '发现新版本,请尝试热更';
            console.log(TAG, `<checkUpdateCallback> 发现新版本,请尝试热更!!! `);
            //有版本需要更新执行热更新
            this._updating = false;
            this.doHotUpdate();
            return;
        default:
            console.log(TAG, `<checkUpdateCallback> event.getEventCode(): ${event.getEventCode()}`);
            return;
    }
    if (this._hallAssetsMgr) {
        this._hallAssetsMgr.setEventCallback(null);
    }
    this._updating = false;
}

/**
 * @Description: 执行热更新逻辑
 * @Date: 2024-01-16 11:49:51
 * @Author: LeeSir add
 * @return {*}
 */
public doHotUpdate() {
    if (this._hallAssetsMgr && !this._updating) {
        this._hallAssetsMgr.setEventCallback(this.updateCallback.bind(this));
        if (this._hallAssetsMgr.getState() === jsb.AssetsManager.State.UNINITED) {
            let url = this.hallMainifestUrl.nativeUrl;
            if (cc.loader.md5Pipe) {
                url = cc.loader.md5Pipe.transformURL(url);
            }
            this._hallAssetsMgr.loadLocalManifest(url);
        }
        this._hallAssetsMgr.update();
        this._updating = true;
    }
}

/**
 * @Description: 热更新回调函数
 * @Date: 2024-01-16 11:50:06
 * @Author: LeeSir add
 * @param {*} event
 * @return {*}
 */
private updateCallback(event) {
    console.log(TAG, "<updateCallback> 热更回调");
    let isUpdateFinished = false;
    let needRestart = false;
    let failed = false;
    let evtMsg = event.getMessage();
    if (evtMsg) {
        this.toolTipslabel.string = 'Updated file: ' + evtMsg;
    }
    switch (event.getEventCode()) {

        case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
            this.toolTipslabel.string = '没有本地manifest文件,跳过热更.';
            failed = true;
            break;
        case jsb.EventAssetsManager.UPDATE_PROGRESSION:
            let percent = event.getPercent();
            if (isNaN(percent)) {
                return;
            }
            console.log(TAG, `<updateCallback> ${event.getDownloadedBytes()} / ${event.getTotalBytes()} (已下载大小/大小总数)`);
            console.log(TAG, `<updateCallback> ${event.getDownloadedFiles()} / ${event.getTotalFiles()} (已下载文件数量/资源总数)`);
            console.log(TAG, `<updateCallback> 当前进度百分比 percent : ${event.getPercent()}`);
            console.log(TAG, `<updateCallback> 当前进度文件百分比 percent by file : ${event.getPercentByFile()}`);
            console.log(TAG, "当前下载文件数: ", event.getDownloadedFiles());
            console.log(TAG, "总文件数: ", event.getTotalFiles());
            let msg = event.getMessage();
            if (msg) {
                this.toolTipslabel.string = '更新的文件:: ' + msg;
            }
            break;
        case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
        case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
            this.toolTipslabel.string = '下载远程manifest文件失败,跳过热更.';
            console.log(TAG, `<updateCallback> ==> 下载远程manifest文件失败,跳过热更. | ${event.getMessage()}`);
            failed = true;
            break;
        case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
            this.toolTipslabel.string = '已经更新到远程最新版本.';
            console.log(TAG, `<updateCallback> ==> 已经更新到远程最新版本. | ${event.getMessage()}`);
            isUpdateFinished = true;
            failed = true;
            break;
        case jsb.EventAssetsManager.UPDATE_FINISHED:
            this.toolTipslabel.string = '更新完成,即将重启游戏. ' + event.getMessage();
            console.log(TAG, `<updateCallback> ==> 更新完成,即将重启游戏. | ${event.getMessage()}`);
            needRestart = true;
            isUpdateFinished = true;
            break;
        case jsb.EventAssetsManager.UPDATE_FAILED:
            this.toolTipslabel.string = '更新失败. ' + event.getMessage();
            console.log(TAG, `<updateCallback> ==> 更新失败. | ${event.getMessage()}`);
            this._updating = false;
            break;
        case jsb.EventAssetsManager.ERROR_UPDATING:
            this.toolTipslabel.string = 'Asset 更新错误: ' + event.getAssetId() + ', ' + event.getMessage();
            console.log(TAG, `<updateCallback> ==> Asset 更新错误: | assetId: ${event.getAssetId()} | ${event.getMessage()}`);
            break;
        case jsb.EventAssetsManager.ERROR_DECOMPRESS:
            this.toolTipslabel.string = event.getMessage();
            break;
        default:
            break;
    }


    let state = this._hallAssetsMgr.getState();
    let evtPercent = (isNaN(event.getPercent()) ? 0 : event.getPercent());
    let info: CustomUpdateDownLoad = {
        downloadedBytes: event.getDownloadedBytes(),
        totalBytes: event.getTotalBytes(),
        downloadedFiles: event.getDownloadedFiles(),
        totalFiles: event.getTotalFiles(),
        percent: (isUpdateFinished ? 1 : evtPercent),
        percentByFile: event.getPercentByFile(),
        code: event.getEventCode(),
        state: Number(state),
        needRestart: isUpdateFinished,
    };
    this.notifyUpdateProgressFunc(info.percent, info);

    if (failed) {
        if (this._hallAssetsMgr) {
            this._hallAssetsMgr.setEventCallback(null);
        }
        this._updating = false;
        return;
    }
    /**重启游戏,并把缓存资源路径前置到搜索路径 */
    if (needRestart) {

        this._remoteVersion = this.getRemoteVersion();
        console.log(TAG, `<updateCallback> remoteVersion: ${this._remoteVersion}`);
        cc.sys.localStorage.setItem(GameLocalKey.CurrentHallVersions, this._remoteVersion);
        if (this._hallAssetsMgr) {
            this._hallAssetsMgr.setEventCallback(null);
        }
        let searchPaths = jsb.fileUtils.getSearchPaths();
        let newPaths = this._hallAssetsMgr.getLocalManifest().getSearchPaths();
        Array.prototype.unshift.apply(searchPaths, newPaths);
        searchPaths = this.trimSearchPath(searchPaths);
        console.log(TAG, `<updateCallback> searchPaths: ${JSON.stringify(searchPaths)}`);
        cc.sys.localStorage.setItem(GameLocalKey.HotUpdateSearchPaths, JSON.stringify(searchPaths));
        jsb.fileUtils.setSearchPaths(searchPaths);
        cc.audioEngine.stopAll();
        this.destroyFunc();
        cc.game.restart();
    }

}

测试调用类

onClickCheckUpdateBtnEvent() {
    this._hallUpdateComp = this.getComponent(hallUpdateComp);
    if (this._hallUpdateComp) {
        this._hallUpdateComp.doCheckUpdate();
    }
}

资源获取方式如下:

1、免费获取方式==>详细实现代码工程逻辑请关注GFanStudio公众号回复 "热更新" 即可获得项目工程下载地址;具体教学视频请关注B站Up主GFanStudio

2、csdn积分下载地址: https://download.csdn.net/download/u011286702/88758563

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GFanStudio-LeeSir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值