type
status
date
slug
summary
tags
category
icon
最近由于项目要从c++移植到js,为的就是热更新。c++因为种种原因无法热更新,所以转到脚本方案了。cocos2dx-js中热更新的代码已经帮我们写好了,我们只需要写一下配置文件就行了。
然而官方的配置文件的文档有点落后,这里有一份好的Cocos2dxJS 热更新
公司的项目是一个棋牌休闲游戏,内部有很多模块(大厅模块一个、若干游戏模块)。需求为游戏需要玩才下载,所以要针对不用的模块编写不同的配置文件。这种机械性的工作当然是交给计算机做啦,写一个脚本完事。
<!-- more --> cocos在开始热更新的时候会先读取本地指定的project.manifest文件,从文件中解析出远程version.manifest的地址,然后下载之。下载完后比较本地的版本号和远端的版本号(此版本非彼坂本),如果不一致就开始更新,更新的时候先下载远端的project.manifest然后读取里面的文件列表,和本地的project.manifest进行比较,如果文件有新增或者相同文件但是md5的数值记录不一样,这时候就会从服务器下载该文件,如果有文件在本地的project.manifest有但是服务器版的project.manifest中没有。cocos就会删除之。
现在最新的代码和资源已经下到了,现在要解决的问题就是怎样让游戏正确的加载下载的资源。这时候就需要添加搜索路径了。
添加游戏搜索路径,这个是jsb才支持的方法。为了方便起见,游戏的默认搜索路径就是根目录。根目录下面有ressrc等。所以只需要在下载的时候,目录结构保持和游戏默认的目录结构一样,然后把下载的根目录添加到搜索路径里面,并且优先级比默认的高。这样的话游戏就能正确读取更新的代码和资源了,添加搜索路径必须在cc.game.run();之前。
cocos2dx-JS中有一个project.json,里面主要保存的是需要加载的js代码。前面有说到,把游戏分成多个模块来加载,启动大厅模块是游戏启动加载的,里面主要有:
  1. 登录
  1. 大厅
  1. 银行
  1. 支付
  1. 设置
游戏代码是在进入游戏的时候去加载的,这样可以除去不必要的js代码加载。综上所述,当大厅更新的时候,需要重启这个游戏 (调用cc.game.restart();即可)。当游戏更新的时候,只需要加载游戏部分的代码就行。
怎么加载制定的js代码呢?别忘了cocos是开源的,我们在cc.game.run();跳进去看看,发现里面有个this.prepare(cc.game.onStart && cc.game.onStart.bind(cc.game),再跳进去看看就发现了this._loadConfig();这个方法,这个看名字就知道是去加载project.json了,往下看就会发现jsList的加载代码。
发现其实就是调用了cc.loader.loadJsWithImg(jsList, callback)这个方法来加载js的。这就好办了,我们只需要把每个游戏模块的js代码文件写到一个属于当前模块的project.json中,然后当游戏下载完之后,解析这个project.json文件,读取里面的jsList加载之就可以。ps (同一份js代码加载两次会出现崩溃,目前不知道原因。如果出现了必须重新加载同一份代码的情况,请重启游戏)

下载游戏

当你的游戏是空的时候,肯定要下载整个游戏。如果下载的全部是碎片文件的话,这样对服务器压力很大。这时候就可以考虑下载zip压缩包。然而这里会有几个问题。
  1. cocos在下载的时候会把version.manifestproject.manifest放到当前下载的设定的根目录,也就是说我们不同模块的根目录必须不一样,如果你设置src/GameModule/LKPY/为李逵劈鱼下载的根目录的话,李逵劈鱼的美术资源就在res/Games/LKPY/下面,导致美术资源文件和project.manifest文件的最近公共祖先不是project.manifest所在的目录。然而解决方案很简单,在project.manifest中填写美术资源的相对路径就行了。(ps:iOS平台不支持相对路径的下载操作,必须修改c++源码 url处理链接c++样例)
  1. 如果zip压缩包内有文件夹,而且下载缓存目录中并没有这个文件夹路径的话解压会错误。这个问题我是通过修改引擎解决的(AssetsManagerEx.cpp中的decompress方法在359// Create a file to store current file.后面添加一行fileUtils->createDirectory(basename(fullPath));)。反正cocosbug也比较多
当游戏为空的时候需要去下载zip资源,游戏不为空的时候,增量更新。但是cocos只会去下载在project.manifest中指定的文件。所以我需要3种类型的project.manifestempty.manifest, compres.manifest, project.manifest
最初只有empty.manifest,里面的版本号为0.0.0,代表没有游戏的情况,地址指向相应服务器的compress.manifest配置文件。 之后cocos就会去下载compress.manifest中的压缩包资源,解压到对应的目录。其中compress.manifest文件中的地址指向的是服务器上的project.manifest文件,之后就可以差量更新了。

编写用于生成配置文件的脚本

介于上述要求,有大量的配置文件需要编写,这些工作当然是交给脚本来处理啦。把需要升级的设定成不同的模块,每个模块都有自己的project.manifest。这里打算用一个模块的json配资文件来生成相应模块的project.manifest(PS:会生成project.manifest compress.manifestempty.manifestproject.json)。

Manifest.json

Android高仿Chrome侧滑返回效果事件分发机制源码解析(二)
Loading...