cocos creator熱更新-菜鳥(niǎo)教程

!寫(xiě)在前面 最后有源碼

說(shuō)下幾個(gè)重要的環(huán)節(jié):首先是version_generator.js文件 可以在官方案例下載??

熱更新管理器 · GitBook

這幾個(gè)屬性可以直接寫(xiě)在version文件里


需要下載nodeJs? 用來(lái)生成?? manifest? 文件


第一次構(gòu)建以后需要在mani.js里加上搜索路勁? main.js文件在build\jsb-default下


if (jsb) { var hotUpdateSearchPaths = localStorage.getItem('HotUpdateSearchPaths'); if (hotUpdateSearchPaths) { jsb.fileUtils.setSearchPaths(JSON.parse(hotUpdateSearchPaths)); }}? ?然后就可以編譯了

? ? ? ? ? ? ? ? ? ? 第一個(gè)apk包基本就這些東西 然后更新包把版本號(hào)提升一下

在隨便改點(diǎn)東西重新構(gòu)建一下? ? ?

? ??然后用nodejs重新生成?manifest文件? ?然后把構(gòu)建后的?project.manifest? ?version.manifest? ? src? res 4個(gè)文件放在服務(wù)器的remote-assets文件下面??


注意服務(wù)器網(wǎng)站的文件類(lèi)型后綴識(shí)別(.json,.manifest,jsc)? 不然可能更新下載失敗

? ? ? ? 如果沒(méi)有檢測(cè)到更新那肯定是?manifest文件的問(wèn)題??


第一次如果沒(méi)有manifest文件 就先構(gòu)建好了 用nodejs生成manifest文件放在屬性里

直接貼代碼? 有問(wèn)題可以留言
cc.Class({

? ? extends: cc.Component,

? ? properties: {

? ? ? ? manifestUrl: {

? ? ? ? ? ? default: null,

? ? ? ? ? ? type: cc.Asset

? ? ? ? },

? ? ? ? versionLabel: cc.Label,


? ? ? ? btn_check: cc.Button,

? ? ? ? btn_update: cc.Button,

? ? ? ? tipLabel: cc.Label,

? ? ? ? byteProgress: cc.ProgressBar,

? ? ? ? byteLabel: cc.Label,

? ? ? ? fileProgress: cc.ProgressBar,

? ? ? ? fileLabel: cc.Label,

? ? },


? ? start() {

? ? ? ? this.updating = false

? ? ? ? this.canRetry = false

? ? ? ? this.btn_update.node.active = false

? ? ? ? this.byteProgress.node.active = false

? ? ? ? this.fileProgress.node.active = false

? ? ? ? this.tipLabel.node.active = false

? ? ? ? if (!cc.sys.isNative) return

? ? ? ? //獲取存儲(chǔ)路徑

? ? ? ? this.storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'remote-asset')

? ? ? ? //版本比較函數(shù)

? ? ? ? this.versionCompareHandle = function (versionA, versionB) {

? ? ? ? ? ? cc.log("JS Custom Version Compare: version A is " + versionA + ', version B is ' + versionB);

? ? ? ? ? ? var vA = versionA.split('.')

? ? ? ? ? ? var vB = versionB.split('.')

? ? ? ? ? ? for (let 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

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //創(chuàng)建資源管理對(duì)象

? ? ? ? this.am = new jsb.AssetsManager('', this.storagePath, this.versionCompareHandle)

? ? ? ? this.am.setVerifyCallback(function (path, asset) {

? ? ? ? ? ? console.log('設(shè)置回調(diào)驗(yàn)證' + asset)

? ? ? ? ? ? var compressed = asset.compressed;

? ? ? ? ? ? var expectedMD5 = asset.md5;

? ? ? ? ? ? var relativePath = asset.path;

? ? ? ? ? ? var size = asset.size;

? ? ? ? ? ? if (compressed) {

? ? ? ? ? ? ? ? this.tipLabel.string = "Verification passed : " + relativePath;

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? else {

? ? ? ? ? ? ? ? this.tipLabel.string = "Verification passed : " + relativePath + ' (' + expectedMD5 + ')';

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? }.bind(this));

? ? ? ? if (cc.sys.os === cc.sys.OS_ANDROID) {

? ? ? ? ? ? // Some Android device may slow down the download process when concurrent tasks is too much.

? ? ? ? ? ? // The value may not be accurate, please do more test and find what's most suitable for your game.

? ? ? ? ? ? this.am.setMaxConcurrentTask(2);

? ? ? ? ? ? console.log('安卓開(kāi)啟雙線程更新模式')

? ? ? ? }

? ? ? ? var url = this.manifestUrl.nativeUrl;

? ? ? ? if (cc.loader.md5Pipe) {

? ? ? ? ? ? url = cc.loader.md5Pipe.transformURL(url);

? ? ? ? }

? ? ? ? this.am.loadLocalManifest(url);

? ? ? ? var version = this.am.getLocalManifest().getVersion();

? ? ? ? console.log('version=' + version)

? ? ? ? this.versionLabel.string = version

? ? ? ? this.fileProgress.progress = 0;

? ? ? ? this.byteProgress.progress = 0;



? ? ? ? //檢查更新

? ? ? ? this.checkUpdate()

? ? },

? ? checkUpdate() {

? ? ? ? this.tipLabel.string = '檢查更新';

? ? ? ? var state = this.am.getState()

? ? ? ? //if (state=== jsb.AssetsManager.State.UNINITED) {

? ? ? ? // Resolve md5 url

? ? ? ? console.log('檢查更新')

? ? ? ? this.am.setEventCallback(this.checkCb.bind(this));

? ? ? ? this.failCount = 0;

? ? ? ? this.am.checkUpdate();

? ? ? ? this.updating = true;

? ? ? ? // }

? ? },


? ? checkCb(event) {

? ? ? ? console.log('Code: ' + event.getEventCode());

? ? ? ? switch (event.getEventCode()) {

? ? ? ? ? ? case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:

? ? ? ? ? ? ? ? this.tipLabel.string = '本地文件丟失'

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:

? ? ? ? ? ? case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:

? ? ? ? ? ? ? ? this.tipLabel.string = "下載遠(yuǎn)程mainfest文件錯(cuò)誤.";

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:

? ? ? ? ? ? ? ? this.tipLabel.string = "已經(jīng)是最新版本.";

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case jsb.EventAssetsManager.NEW_VERSION_FOUND:? ? //顯示更新按鈕 調(diào)用hotUpdate方法

? ? ? ? ? ? ? ? this.tipLabel.node.active = true

? ? ? ? ? ? ? ? this.tipLabel.string = '有新版本發(fā)現(xiàn),請(qǐng)點(diǎn)擊更新.';

? ? ? ? ? ? ? ? this.btn_update.node.active = true

? ? ? ? ? ? ? ? this.btn_check.interactable = false;


? ? ? ? ? ? ? ? break;

? ? ? ? ? ? default:

? ? ? ? ? ? ? ? return;

? ? ? ? }

? ? ? ? this.am.setEventCallback(null);

? ? ? ? this.updating = false;

? ? },


? ? hotUpdate: function () {

? ? ? ? if (this.am && !this.updating) {

? ? ? ? ? ? console.log('更新')

? ? ? ? ? ? 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);

? ? ? ? ? ? ? ? console.log('本地地址' + url)

? ? ? ? ? ? }

? ? ? ? ? ? this.failCount = 0;

? ? ? ? ? ? this.am.update();

? ? ? ? ? ? this.updating = true;

? ? ? ? }

? ? },

? ? updateCb(event) {

? ? ? ? console.log('Code: ' + event.getEventCode());

? ? ? ? var needRestart = false;

? ? ? ? var failed = false;

? ? ? ? this.byteProgress.node.active = true

? ? ? ? this.fileProgress.node.active = true

? ? ? ? switch (event.getEventCode()) {

? ? ? ? ? ? case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:

? ? ? ? ? ? ? ? this.tipLabel.string = '本地版本文件丟失,無(wú)法更新.';

? ? ? ? ? ? ? ? failed = true;

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case jsb.EventAssetsManager.UPDATE_PROGRESSION:

? ? ? ? ? ? ? ? this.byteProgress.progress = event.getPercent();

? ? ? ? ? ? ? ? this.fileProgress.progress = event.getPercentByFile();

? ? ? ? ? ? ? ? this.fileLabel.string = event.getDownloadedFiles() + ' / ' + event.getTotalFiles();

? ? ? ? ? ? ? ? this.byteLabel.string = event.getDownloadedBytes() + ' / ' + event.getTotalBytes();

? ? ? ? ? ? ? ? var msg = event.getMessage();

? ? ? ? ? ? ? ? if (msg) {

? ? ? ? ? ? ? ? ? ? this.tipLabel.string = 'Updated file: ' + msg;

? ? ? ? ? ? ? ? ? ? console.log(event.getPercent() / 100 + '% : ' + msg);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:

? ? ? ? ? ? case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:

? ? ? ? ? ? ? ? this.tipLabel.string = '下載遠(yuǎn)程版本文件失敗.';

? ? ? ? ? ? ? ? failed = true;

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:

? ? ? ? ? ? ? ? this.tipLabel.string = '當(dāng)前為最新版本.';

? ? ? ? ? ? ? ? failed = true;

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case jsb.EventAssetsManager.UPDATE_FINISHED:

? ? ? ? ? ? ? ? this.tipLabel.string = '更新完成. ' + event.getMessage();

? ? ? ? ? ? ? ? needRestart = true;

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case jsb.EventAssetsManager.UPDATE_FAILED:

? ? ? ? ? ? ? ? this.proc.string = '更新失敗. ' + event.getMessage();

? ? ? ? ? ? ? ? this.btn_rectry.interactable = true;

? ? ? ? ? ? ? ? this.updating = false;

? ? ? ? ? ? ? ? this.canRetry = true;

? ? ? ? ? ? ? ? this.btn_update.interactable = false

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case jsb.EventAssetsManager.ERROR_UPDATING:

? ? ? ? ? ? ? ? this.tipLabel.string = '資源更新錯(cuò)誤: ' + event.getAssetId() + ', ' + event.getMessage();

? ? ? ? ? ? ? ? this.btn_update.interactable = false

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case jsb.EventAssetsManager.ERROR_DECOMPRESS:

? ? ? ? ? ? ? ? this.tipLabel.string = event.getMessage();

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? default:

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? ? ? if (failed) {

? ? ? ? ? ? this.am.setEventCallback(null);

? ? ? ? ? ? this.updating = false;

? ? ? ? }

? ? ? ? //下載完成

? ? ? ? if (needRestart) {

? ? ? ? ? ? this.am.setEventCallback(null);

? ? ? ? ? ? console.log('熱更完成')

? ? ? ? ? ? // Prepend the manifest's search path

? ? ? ? ? ? var searchPaths = jsb.fileUtils.getSearchPaths();

? ? ? ? ? ? var newPaths = this.am.getLocalManifest().getSearchPaths();

? ? ? ? ? ? console.log(JSON.stringify(newPaths));

? ? ? ? ? ? Array.prototype.unshift.apply(searchPaths, newPaths);

? ? ? ? ? ? cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));

? ? ? ? ? ? jsb.fileUtils.setSearchPaths(searchPaths);

? ? ? ? ? ? cc.audioEngine.stopAll();

? ? ? ? ? ? cc.game.restart();

? ? ? ? }

? ? },


? ? retry: function () {

? ? ? ? if (!this.updating && this.canRetry) {

? ? ? ? ? ? this.panel.retryBtn.active = false;

? ? ? ? ? ? this.canRetry = false;

? ? ? ? ? ? this.tipLabel.string = 'Retry failed Assets...';

? ? ? ? ? ? this.am.downloadFailedAssets();

? ? ? ? }

? ? },

});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容