cocos2d-js 在线更新代码脚本 动态更新脚本程序 热更新 绕过平台
2014年8月15日补充
cocos2d-js 3.0 rc0 的AssetsManager有缺陷,有一些注意点:(可以阅读源代码发现)
1、旧manifest中有,但新manifest中没有的文件(Assets),会被删除;旧的没有,新的有,会正常下载。
2、groupversion暂时没什么意义,并无法达到这位博主所谓的增量更新:
https://github.com/faint2death/cocos2d-js/blob/master/assetsmanager.md。暂时只在版本比较中用到,并没有在计算增量值中用到。
3、下载过程中N个文件其中某个遇到错误,已下载的文件还是会妥妥的覆盖了旧文件,这样会造成更新了一半的尴尬情况。
2014年8月19日补充
cocos2d-js 3.0 rc2 的AssetsManager依然有没有确保全部同步更新的bug。本来想彻底解决这个问题,但无奈时间有限,没有彻底理解AssetsManager多个类的作用。彻底解决的事,还是留给触控去解决吧。
经过小修改,已经可以确保同步更新资源。其实做的工作就是:等最终全部下载完成后再解压文件,这样的改动是最小的。
使用这个更新包:https://github.com/kenkozheng/cocos2d-js/tree/master/modified-AssetsManager
覆盖本地2个目录相应的文件:
【项目路径】frameworksjs-bindingscocos2d-xextensionsassets-manager(新建工程时复制出来的)
【库路径】E:cocos2d-js-v3.0-rc2frameworksjs-bindingscocos2d-xextensionsassets-manager
使用方法: 1、所有js必须使用zip打包,但不强求只打包为1个文件。但不同zip不要有重复的js。 2、非js可以用zip,也可以直接列出。 由于确保所有资源都下载完成后才解压js,所以玩家即使N次更新失败,还是会妥妥的停留在上一版。
建议:
1、自第一次发布后,历次更新的代码都打包在一个js.zip中,每次只更新这个js.zip。这样好处是,保证所有代码是同步的,即使没更新到,玩家也就停留在上一版。例如第一次更新,有1.js,那么js.zip只有1.js;第二次更新2.js,那么js.zip就得包含1.js和2.js,这样避免一些跳版本更新的玩家出问题。
2、
非代码资源,避免修改,可以直接用新文件,但不要替换旧文件,这样目的是避免多次版本更新造成新旧混乱。设想2次更新都是zip包,两个zip包都有1.png,这时候有个跳版本更新的玩家,就会下载2个zip包,但先后顺序是不可控的。
3、每次更新manifest文件必须保留以前的assets配置,不能删除。否则,如果删了以前的assets配置,客户端会跟随着删除相应的文件。
一、cocos2d-js 动态更新的基本思路
二、程序发布步骤
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:,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); } case cc.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST: case cc.EventAssetsManager.ERROR_PARSE_MANIFEST: cc.log("Fail to download manifest file,update skipped."); that.loadGame(); case cc.EventAssetsManager.ALREADY_UP_TO_DATE: cc.log("ALREADY_UP_TO_DATE."); that.loadGame(); case cc.EventAssetsManager.UPDATE_FINISHED: cc.log("Update finished."); that.loadGame(); 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(); } case cc.EventAssetsManager.ERROR_UPDATING: cc.log("Asset update error: " + event.getAssetId() + "," + event.getMessage()); that.loadGame(); case cc.EventAssetsManager.ERROR_DECOMPRESS: cc.log(event.getMessage()); that.loadGame(); default: break; } }); cc.eventManager.addListener(listener,1); this._am.update(); cc.director.runScene(this); } this.schedule(this.updateProgress,0.5); },loadGame:jsList是jsList.js的变量,记录全部js。 cc.loader.loadJs(["src/jsList.js"],255); line-height:1.5!important">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();
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"], //貌似这个对jsb是无效的,只有html5才有效 "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" : [ ] }
三、动态更新测试
|