cocos2d-js 在线更新代码脚本 动态更新脚本程序 热更新

一、cocos2d-js 动态更新的基本思路

动态更新的好处不言而喻,不需要重新上架审核,能节省很多时间,也能让用户尽快使用上最新的版本,减少下载的成本。

  • 官方BETA版本后提供了AssetsManager类,可以完成动态更新的步骤,说明:https://github.com/chukong/cocos-docs/blob/master/manual/framework/html5/v3/assets-manager/zh.md
  • cocos2d程序安装后,以Android为例,程序存在于2个地方:apk安装目录(/data/dalvik-cache),apk数据目录(/data/data/[包名])
  • AssetsManager根据projec.manifest文件的配置,把新文件下载到apk数据目录,并默认把这个下载目录设置为最优先搜索的地方。(api:)
  • project.json文件中指定的js文件,将在程序main.js启动前就加载完。main.js不需要写到这个list中。所以需要动态更新的js,不能列在这个json中
  • 除了main.js外,把其他js列到一个文件中:src/jsList.js。AssetsManager检查完之后,先加载这个jsList.js,然后根据里边的配置再加载全部js。

二、程序发布步骤

本文参考:https://github.com/faint2death/cocos2d-js/blob/master/assetsmanager.md,但配置的方式不一样,本文更偏于使用官方的配置。按参考文章的写法,更新多次之后,project.manifest文件会很大,这影响用户更新的速度。

1、修改main.js,加载AssetsManager功能

cc.game.onStart = function(){
    cc.view.setDesignResolutionSize(800, 450, cc.ResolutionPolicy.SHOW_ALL);
    cc.view.resizeWithBrowserSize(true); 

    var failCount = 0;
    var maxFailCount = 1;   //最大错误重试次数

    /**
     * 自动更新js和资源
     */
    var AssetsManagerLoaderScene = cc.Scene.extend({
        _am:null,
        _progress:null,
        _percent:0,
        run:function(){
            if (!cc.sys.isNative) {
                this.loadGame();
                return;
            }

            var layer = new cc.Layer();
            this.addChild(layer);
            this._progress = new cc.LabelTTF.create("update 0%", "Arial", 12);
            this._progress.x = cc.winSize.width / 2;
            this._progress.y = cc.winSize.height / 2 + 50;
            layer.addChild(this._progress);

            var storagePath = (jsb.fileUtils ? jsb.fileUtils.getWritablePath() : "./");

            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 cc.EventListenerAssetsManager(this._am, function(event) {
                    switch (event.getEventCode()){
                        case cc.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
                            cc.log("No local manifest file found, skip assets update.");
                            that.loadGame();
                            break;
                        case cc.EventAssetsManager.UPDATE_PROGRESSION:
                            that._percent = event.getPercent();
                            cc.log(that._percent + "%");
                            var msg = event.getMessage();
                            if (msg) {
                                cc.log(msg);
                            }
                            break;
                        case cc.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
                        case cc.EventAssetsManager.ERROR_PARSE_MANIFEST:
                            cc.log("Fail to download manifest file, update skipped.");
                            that.loadGame();
                            break;
                        case cc.EventAssetsManager.ALREADY_UP_TO_DATE:
                            cc.log("ALREADY_UP_TO_DATE.");
                            that.loadGame();
                            break;
                        case cc.EventAssetsManager.UPDATE_FINISHED:
                            cc.log("Update finished.");
                            that.loadGame();
                            break;
                        case cc.EventAssetsManager.UPDATE_FAILED:
                            cc.log("Update failed. " + event.getMessage());
                            failCount++;
                            if (failCount < maxFailCount)
                            {
                                that._am.downloadFailedAssets();
                            }
                            else
                            {
                                cc.log("Reach maximum fail count, exit update process");
                                failCount = 0;
                                that.loadGame();
                            }
                            break;
                        case cc.EventAssetsManager.ERROR_UPDATING:
                            cc.log("Asset update error: " + event.getAssetId() + ", " + event.getMessage());
                            that.loadGame();
                            break;
                        case cc.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(){
            //jsList是jsList.js的变量,记录全部js。
            cc.loader.loadJs(["src/jsList.js"], function(){
                cc.loader.loadJs(jsList, function(){
                    cc.director.runScene(new MainScene());
                });
            });
        },

        updateProgress:function(dt){
            this._progress.string = "update" + this._percent + "%";
        },

        onExit:function(){
            cc.log("AssetsManager::onExit");

            this._am.release();
            this._super();
        }
    }); 

    var scene = new AssetsManagerLoaderScene();
    scene.run();
};
cc.game.run();

2、建立jsList.js。使用固定名字jsList,这个跟第1步的代码相对应。

var jsList = [
    "src/resource.js",
    "src/app.js"
]

3、修改project.json。加入extensions模块,删除jsList的内容。

{
    "project_type": "javascript",

    "debugMode" : 1,
    "showFPS" : true,
    "frameRate" : 60,
    "id" : "gameCanvas",
    "renderMode" : 0,
    "engineDir":"frameworks/cocos2d-html5",

    "modules" : ["cocos2d", "extensions"],

    "jsList" : [ 

    ]
}

4、项目res目录增加一个project.manifest文件,AssetsManager.js里会用到。url填写自己服务器的地址,packageUrl是准备动态更新的文件的存放目录。

{
    "packageUrl" : "http://192.168.1.11:8000/res",
    "remoteManifestUrl" : "http://192.168.1.11:8000/res/project.manifest",
    "remoteVersionUrl" : "http://192.168.1.11:8000/res/version.manifest",
    "version" : "1.0.1",
    "engineVersion" : "3.0 rc0",
    "assets" : {

    },

    "searchPaths" : [
    ]
}

5、打包程序。此时即使没有网络,也已经可以运行基础版本。

三、动态更新测试

1、服务器放置version.manifest和新的project.manifest。

AssetsManager会先检查version.manifest,判断是否有更新。如果有,再拉取project.manifest。可以说version.manifest就是缩小版的project.manifest,只有头几行,两者一致。

version.manifest:

{
    "packageUrl" : "http://192.168.1.11:8000/res",
    "remoteManifestUrl" : "http://192.168.1.11:8000/res/project.manifest",
    "remoteVersionUrl" : "http://192.168.1.11:8000/res/version.manifest",
    "version" : "1.0.1",
    "engineVersion" : "3.0 rc0"
}

project.manifest:

{
    "packageUrl" : "http://192.168.1.11:8000/res",
    "remoteManifestUrl" : "http://192.168.1.11:8000/res/project.manifest",
    "remoteVersionUrl" : "http://192.168.1.11:8000/res/version.manifest",
    "version" : "1.0.1",
    "engineVersion" : "3.0 rc0",
    "assets" : {
        "src/app.zip" : {
            "md5" : "D07D260D8072F786A586A6A430D0E98B",
            "compressed" : true
        }
    },

    "searchPaths" : [
    ]
}

manifest这里使用了官方说明没有提到的compressed,src/app.zip并没有在初始打包的程序中,这个只是更新用的。指定了compressed=true,AssetsManager下载后会自动解压这个文件,并保留这个文件。这样就可以减少网络传输的文件大小。

app.zip压缩的是app.js,解压后将覆盖初始化安装的app.js,从而实现了动态更新。

这里可以多次更新,不断更新version号即可,每次AssetsManager会检查文件是否存在、文件md5是否一致,如果不存在或者md5不一致都会重新下载。

2、无需重新打包发布,直接打开cocos2d程序,可以看到update的字样,如果打开了logcat,也可以看到对应的日志。

cocos2d-js 在线更新代码脚本 动态更新脚本程序 热更新

时间: 2024-10-26 20:22:55

cocos2d-js 在线更新代码脚本 动态更新脚本程序 热更新的相关文章

Unity3D热更新全书-何谓热更新,为何热更新,如何热更新

首先来赞叹一下中文,何谓为何如何,写完才发现这三个词是如此的有规律. 为何赞叹中文?因为这是一篇针对新手程序员的文字,是一节语文课. 然后来做一下说文解字,也就是 何谓热更新 热更新,每个程序员一听就明白,但是它语出何处,究竟表达了什么含义,到底代表了什么,对技术有什么要求,对经验相对较少的程序员来说可能就有一层神秘面纱了. 热更新,是对hot update 或者 hot fix的翻译,计算机术语,表示在不停机的前提下对系统进行更改. hot 就是热,机器运行会发烫,hot就是不停机的意思. 热

ios app 实现热更新(无需发新版本号实现app加入新功能)

眼下可以实现热更新的方法,总结起来有下面三种 1. 使用FaceBook 的开源框架 reactive native,使用js写原生的ios应用 ios app能够在执行时从server拉取最新的js文件到本地.然后执行,由于js是一门动态的 脚本语言.所以可以在执行时直接读取js文件执行,也因此可以实现ios的热更新 2. 使用lua 脚本.lua脚本如同js 一样,也能在动态时被.之前愤慨的小鸟使用 lua脚本做的一个插件 wax,能够实现使用lua写ios应用.热更新时,从server拉去

我使用的 unity 热更新方案 JSB(求小编 推荐一下)

今天周五 ,明天没有什么事情,可以安心写一些博客. 今天聊 两个话题 一 , unity热更新的窘境 二 ,我所使用的unity 热更新方案JSB ======================================热更新的窘境============================================= (1)其实unity 热更新到瓶颈是 ios 的 系统本身 ,禁止你 jit .说白了,内存中代码,系统本身不让你执行. 安卓 系统,桌面 系统,本身都支持 动态直接替换d

ios app 实现热更新(无需发新版本实现app添加新功能)

目前能够实现热更新的方法,总结起来有以下三种 1. 使用FaceBook 的开源框架 reactive native,使用js写原生的iOS应用 ios app可以在运行时从服务器拉取最新的js文件到本地,然后执行,因为js是一门动态的 脚本语言,所以可以在运行时直接读取js文件执行,也因此能够实现ios的热更新 2. 使用lua 脚本.lua脚本如同js 一样,也能在动态时被.之前愤怒的小鸟使用 lua脚本做的一个插件 wax,可以实现使用lua写ios应用.热更新时,从服务器拉去lua脚本

[Cocos2d-x]Lua 资源热更新

什么是热更新 所谓的热更新,指的是客户端的更新. 大致的流程是,客户端在启动后访问更新的URL接口,根据更新接口的反馈,下载更新资源,然后使用新的资源启动客户端,或者直接使用新资源不重启客户端. 热更新代码使用到的场景 情人节快到了,你想要组织一个游戏内活动,错过时机肯定是你最不想要看到的结果. 当你发现一个严重的bug. 当你想要添加一些新的场景或者关卡来延长游戏的生命. 以及非常多其他的情况... 在Cocos2d-x引擎中的如何实现热更新 LuaEngine LuaEngine是一个脚本能

Unity3D热更新全书FAQ

只要有程序员朋友们问过两次的问题 就会收录在此FAQ中 1.C#Light对比LUA有什么好处 C#Light是静态类型脚本语言,语法同C#,Lua是动态类型脚本语言,这两种都有人喜欢. 我更喜欢静态类型,于是有了C#Light 2.C#Light性能怎么样 C#Light和Unilua 和ulua都做过简单性能测试,比Unilua快,和ulua各有胜负 3.C#Light IOS可以使用么 完全可以,均妥善测试 4.为什么C#Light例子和NGUI一起用会编译不过 因为Unity没有库的概念

React Native之code-push的热更新(ios android)

React Native之code-push的热更新(ios android) React Native支持大家用React Native技术开发APP,并打包生成一个APP.在动态更新方面React Native只是提供了动态更新的基础,对将应用部署到哪里,如何进行动态更新并没有支持的那么完善.好在微软开发了CodePush,填补React Native 应用在动态更新方面的空白.CodePush 是微软提供的一套用于热更新 React Native 和 Cordova 应用的服务.下面将向大

ionic2新手入门整理,搭建环境,创建demo,打包apk,热更新,优化启动慢等避坑详解

onic官方文档链接:http://ionicframework.com/docs/ 如果是新的环境会有很多坑,主要是有墙,请仔细阅读每个步骤 文档包含以下内容: l  环境搭建 l  创建demo并调试运行 l  打包APK l  添加支持热更新 l  优化启动慢问题 l  常用命令 1.      环境搭建 需要安装以下软件和插件(Android): l  安装nodeJS(自带npm) l  配置cnpm  (使用淘宝镜像取代npm) l  安装cordova和ionic2 l  安装JA

Unity官方公布热更新方案性能对比

孙广东  2016.3.11 Unity应用的iOS热更新 作者:丁治宇 Unity TechnologiesChina Agenda ?  什么是热更新 ?  为何要热更新 ?  如何在iOS 上对Unity 应用进行热更新 ?  支持Unity iOS 热更新的各种Lua 插件的对比 什么是热更新 ? 广义定义 ? 无需关闭服务器,不停机状态下修复漏洞,更新资源等,重点是更新逻辑代码. ? 狭义定义( iOS热更新) ? 无需将代码重新打包提交至AppStore,即可更新客户端的执行代码,即