您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-js 3.0 热更新

2014-10-21 09:16 190 查看
首先搭建服务器的配置文件的目录:



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值的意义:

如果修改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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cocos2d cocos2d-js3.0