热更新的使用方法参考自http://www.cnblogs.com/kenkofox/p/3906681.html以及官网资料,感谢大神的资料。
有几个要注意的地方:
1、建议自己写一个AssetsManager类:
/**
* 自动更新js和资源
*/
var AssetsManagerLoaderScene = cc.Scene.extend({
_am :null,
_progress :null,
_percent :0,
_failCount :0, //失败次数
_maxFailCount :1, //最大错误重试次数
run:function(){
if (!cc.sys.isNative) {
this.loadGame();
return;
}
var layer = new cc.Layer();
this.addChild(layer);
this._progress = new cc.LabelTTF("update 0%", "Arial", 12);
this._progress.setPosition(cc.winSize.width / 2, cc.winSize.height / 2 + 50);
layer.addChild(this._progress);
var storagePath = (jsb.fileUtils ? jsb.fileUtils.getWritablePath() : "/");
cc.log("storagePath is " + storagePath);
this._am = new jsb.AssetsManager("res/project.manifest", storagePath);
this._am.retain();
if (!this._am.getLocalManifest().isLoaded())
{
cc.log("Fail to update assets, step skipped.");
this.loadGame();
}
else
{
var that = this;
var listener = new jsb.EventListenerAssetsManager(this._am, function(event) {
switch (event.getEventCode()){
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
cc.log("ERROR_NO_LOCAL_MANIFEST.");
that.loadGame();
break;
case jsb.EventAssetsManager.UPDATE_PROGRESSION:
that._percent = event.getPercent();
cc.log("UPDATE_PROGRESSION: " + that._percent + "%");
cc.log("UPDATE_PROGRESSION: " + event.getMessage());
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
cc.log("ERROR_DOWNLOAD_MANIFEST.");
that.loadGame();
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
cc.log("ALREADY_UP_TO_DATE.");
that.loadGame();
break;
case jsb.EventAssetsManager.UPDATE_FINISHED:
cc.log("UPDATE_FINISHED.");
that.loadGame();
break;
case jsb.EventAssetsManager.UPDATE_FAILED:
cc.log("UPDATE_FAILED: " + event.getMessage());
that._failCount++;
if (that._failCount < that._maxFailCount)
{
that._am.downloadFailedAssets();
}
else
{
cc.log("Reach maximum fail count, exit update process");
that._failCount = 0;
that.loadGame();
}
break;
case jsb.EventAssetsManager.ERROR_UPDATING:
cc.log("ERROR_UPDATING: " + event.getAssetId() + ", " + event.getMessage());
that.loadGame();
break;
case jsb.EventAssetsManager.ERROR_DECOMPRESS:
cc.log("ERROR_DECOMPRESS: " + event.getMessage());
that.loadGame();
break;
default:
break;
}
});
cc.eventManager.addListener(listener, 1);
this._am.update();
cc.director.runScene(this);
}
this.schedule(this.updateProgress, 0.5, cc.REPEAT_FOREVER, 0);
},
onExit:function(){
cc.log("AssetsManager::onExit");
this._am.release();
this._super();
},
loadGame:function(){//jsList是jsList.js的变量,记录全部js
cc.loader.loadJs(["src/Global/Data/jsList.js"], function(){
cc.loader.loadJs(jsList, function(err){
cc.LoaderScene.preload(g_resources, function () {
if(cc.sys.localStorage.getItem("isLogin") == "true"){
cc.director.runScene(new MainScene());
}
else{
cc.director.runScene(new LoginScene());
}
}, this);
});
});
},
updateProgress:function(dt){
this._progress.setString("update " + this._percent + "%");
}
});
在main.js中将跳转场景的代码替换为:(原来的cc.LoaderScene.preload放到上面AssetsManager类的97行处)
cc.game.onStart = function(){
if(!cc.sys.isNative && document.getElementById("cocosLoading"))
document.body.removeChild(document.getElementById("cocosLoading"));
cc.view.enableRetina(cc.sys.os === cc.sys.OS_IOS ? true : false);
cc.view.adjustViewPort(true);
cc.view.setDesignResolutionSize(750, 1334, cc.ResolutionPolicy.SHOW_ALL);
cc.view.resizeWithBrowserSize(true);
var scene = new AssetsManagerLoaderScene();
scene.run();
};
cc.game.run();
2、extensions模块并不是必须添加的,但需不需要添加其中的子模块就不知道了,我的项目中添加了cocostudio和editbox模块;
3、在project.json的"jsList"中只添加AssetsManager类和不会需要热更新的类;
4、特别注意:放在服务器的project.manifest文件中的"assets"对象中的key值路径必须与自己项目中相应文件的路径对应,例如:在更新
src\MainScene\MessageLayer\Message.js 时,key值为"src/MainScene/MessageLayer/Message.zip",zip文件放到相应路径下;
5、js文件、图片等都可以打包,减少传输的数据量;
6、网上有说的groupVersions增量更新的说法,我使用后报错了,没有成功;
7、服务器如果没有热更新需要的文件,AssetsManager中会下载失败,但不会影响程序正常运行。