首先搭建服务器的配置文件的目录:
img文件夹是用来存放图片,js文件夹是存放需要更新的js文件,res1_0_1.zip是把img和js2个文件夹打包的zip(客户端将下载该zip并解压),
js的文件夹有2个重要文件imgFiles.js(用来加载图片文件)和jsFiles.js(用来加载需要更新的js文件,客户端更新完资源后将加载该脚本):
jsFiles.js我的内容如下:
var jsFiles = [//每个不同版本的js脚本直接在后面追加
"js/imgFiles.js",
"js/app.js"
];
imgFiles.js内容我的如下:
var res2 = {//每个不同版本的图片直接在后面追加
HelloWorld_png : "img/HelloWorld.png",
CloseNormal_png : "img/CloseNormal.png",
CloseSelected_png : "img/CloseSelected.png"
};
//追加更新的资源res已在原来的第一版的包中定义了
for (var i in res2) {
res[i]=res2[i];
}
for (var i in res2) {
g_resources.push(res2[i]);
}
解释下res变量和g_resources是客户端文件中定义的,我是先加载客户端的本地资源,然后才是加载更新的资源
project.manifest文件是下载配置的信息,我的如下:
{
"packageUrl" : "http://xxxxxxx/update_liuYao/",
"remoteManifestUrl" : "http://xxxxxxx/update_liuYao/project.manifest",
"remoteVersionUrl" : "http://xxxxxxxxx/update_liuYao/version.manifest",
"version" : "1.0.1",
"engineVersion" : "3.0 beta",
"assets" : {
"update1" : {
"path" : "res1_0_1.zip",
"md5" : "1.0.1",
"compressed" : true,
"group" : "1"
}
},
"searchPaths" : [
]
}
xxxxx代表你的服务器的地址(以下雷同),解释下参数:
- packageUrl : 远程资源的下载根路径。
- remoteVersionUrl : 远程版本文件的路径,用来判断服务器端是否有新版本的资源。
- remoteManifestUrl : 远程配置文件的路径,包含版本信息以及所有资源信息。
- version : 配置文件对应的版本。
- engineVersion : 配置文件对应的引擎版本。
- assets : 所有资源信息。
- path: 键代表资源的相对路径(相对于packageUrl)。
- md5 : md5值代表资源文件的版本信息(随便写).
- compressed : [可选项] 如果值为true,文件被下载后会自动被解压,目前仅支持zip压缩格式。
- searchPaths : 需要添加到cocos2d引擎中的搜索路径列表。
如果修改MD5值,如本文把1.0.1改成1.0.1.1那么当你新增更新第2个版本资源时,project.manifest文件现在假设修改如下:
{
"packageUrl" : "http://xxxxxx/update_liuYao/",
"remoteManifestUrl" : "http://xxxxxx/update_liuYao/project.manifest",
"remoteVersionUrl" : "http://xxxxxx/update_liuYao/version.manifest",
"version" : "1.0.2",
"engineVersion" : "3.0 beta",
"assets" : {
"update1" : {
"path" : "res1_0_1.zip",
"md5" : "1.0.1.1",
"compressed" : true,
"group" : "1"
},
"update2" : {
"path" : "res1_0_2.zip",
"md5" : "1.0.2",
"compressed" : true,
"group" : "1"
}
},
"searchPaths" : [
]
}
现在打算更新第2个版本res1_0_2.zip,那么曾经更新过res1_0_1.zip的用户将会再次冲下该文件,如果不改update1的MD5值仍然为
1.0.1的话更新过res1_0_1.zip用户将不会再次更新只更新res1_0_2.zip,而没有更新过res1_0_1.zip的用户将会2个文件都更新。
version.manifest为文件版本信息,客户端的AssetsManager首先会下载version.manifest文件,如果有更新的版本(下载后会跟客户端的project.manifest的版本信息比较),那么才会去下载project.manifest,我的如下:
{
"packageUrl" : "http://xxxxxx/update_liuYao/",
"remoteManifestUrl" : "http://xxxxxx/update_liuYao/project.manifest",
"remoteVersionUrl" : "http://xxxxxxx/update_liuYao/version.manifest",
"version" : "1.0.1",
"engineVersion" : "3.0 beta"
}
下面解说客户端:
ios模拟器测试经过更新的沙盒
首先在res下建立个project.manifest文件:
内容如下:
{
"packageUrl" : "http://xxxxxx/update_liuYao/",
"remoteManifestUrl" : "http://xxxxx/update_liuYao/project.manifest",
"remoteVersionUrl" : "http://xxxxxxx/update_liuYao/version.manifest",
"version" : “1.0.0”,
"engineVersion" : "3.0 beta",
"assets" : {
},
"searchPaths" : [
]
}
在src建立AssetsManager.js文件:
/**
* Created by zcl on 14-10-18.
*/
var __failCount = 0;
var AssetsManagerLoaderScene = cc.Scene.extend({
_am:null,
_progress:null,
_percent:0,
_percentByFile:0,
run:function(){
if (!cc.sys.isNative) {
this.loadGame();
return;
}
var layer = new cc.Layer();
this.addChild(layer);
this._progress = new cc.LabelTTF.create("0%", "Arial", 12);
this._progress.x = cc.winSize.width / 2;
this._progress.y = cc.winSize.height / 2 + 50;
layer.addChild(this._progress);
// android: /data/data/com.huanle.magic/files/
var storagePath = (jsb.fileUtils ? jsb.fileUtils.getWritablePath() : "./")+"update/";
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("No local manifest file found, skip assets update.");
that.loadGame();
break;
case jsb.EventAssetsManager.UPDATE_PROGRESSION:
that._percent = event.getPercent();
that._percentByFile = event.getPercentByFile();
cc.log(that._percent + "%");
var msg = event.getMessage();
if (msg) {
cc.log(msg);
}
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
cc.log("Fail to download manifest file, update skipped.");
that.loadGame();
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
case jsb.EventAssetsManager.UPDATE_FINISHED:
jsb.fileUtils.addSearchPath(storagePath+"js");
cc.log("Update finished."+jsb.fileUtils.fullPathForFilename("jsFiles.js"));
if(jsb.fileUtils.fullPathForFilename("jsFiles.js")!="jsFiles.js"){//找到文件说明更新过资源,加载更新的资源
cc.loader.loadJs(["js/jsFiles.js"], function(err){
cc.loader.loadJs(jsFiles, function(err){
});
});
}
that.loadGame();
break;
case jsb.EventAssetsManager.UPDATE_FAILED:
cc.log("Update failed. " + event.getMessage());
//再次尝试更新
__failCount ++;
if (__failCount < 5)
{
that._am.downloadFailedAssets();
}
else
{
cc.log("Reach maximum fail count, exit update process");
__failCount = 0;
that.loadGame();
}
break;
case jsb.EventAssetsManager.ERROR_UPDATING:
cc.log("Asset update error: " + event.getAssetId() + ", " + event.getMessage());
that.loadGame();
break;
case jsb.EventAssetsManager.ERROR_DECOMPRESS:
cc.log(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);
},
loadGame:function(){
cc.director.runScene(new HelloWorldScene());
},
updateProgress:function(dt){
this._progress.string = "" + this._percent;
},
onExit:function(){
cc.log("AssetsManager::onExit");
this._am.release();
this._super();
}
});
在project.json的文件增加AssetsManager.js文件如下:
{
"project_type": "javascript",
"debugMode" : 1,
"showFPS" : true,
"frameRate" : 60,
"id" : "gameCanvas",
"renderMode" : 0,
"engineDir":"frameworks/cocos2d-html5",
"modules" : ["cocos2d"],
"jsList" : [
"src/resource.js",
"src/AssetsManager.js"
]
}
此处resource.js可以加载本地的图片:
var res = {
HelloWorld_png2 : "res/HelloWorld.png",
CloseNormal_png : "res/CloseNormal.png",
CloseSelected_png : "res/CloseSelected.png"
};
var g_resources = [];
for (var i in res) {
g_resources.push(res[i]);
}
修改main.js文件:
cc.game.onStart = function(){
cc.view.adjustViewPort(true);
cc.view.setDesignResolutionSize(1536, 2048, cc.ResolutionPolicy.EXACT_FIT);
cc.view.resizeWithBrowserSize(true);
//load resources
cc.LoaderScene.preload(g_resources, function () {
cc.log("load ben di resources,加载原有本地资源完毕!");
},this);
var scene = new AssetsManagerLoaderScene();
scene.run();
};
cc.game.run();
平时生活中各种琐事比较多写的博文比较少,然本人一向本着事情要么不做要做就用心做,故而本人在此希望各位同道能本着开源,有责任的态度,以此减少后学者的困扰。
另本人推荐另一篇比较好的文章:https://github.com/faint2death/cocos2d-js/blob/master/assetsmanager.md。