【步兵 cocos2dx】热更新(上)

来源:互联网 发布:面向对象编程思想 编辑:程序博客网 时间:2024/05/22 12:53

【步兵 cocos2dx】lua的热更新 By EOS.

之前写好的热更,基本可以在项目中使用,接下来拿出来跟大家分享一下。
话不多说,直接进入正题。。。总感觉两行长度差太多不舒服,现在好了。


lua的热更新

因为lua脚本的独立性和模块管理的灵活性,所以我们可以在程序不重新启动的情况下,
来卸载和重新加载lua脚本,但是因为独立,所以可以在任何结点进行重新加载,
但由于全局表本身和资源可能引发各种各样的问题,所以一般在程序的一开始今人热更新。
省去很多麻烦,当然如果提示性的下载再重新加载也是没有问题的,
前提是能够兼容用户不更新情况下,还保持游戏的一致性(基本上就是只更新资源了)。
核心代码:

--先卸载package.loaded[MODEL_NAME] = nil--cocos路径缓存,记得清,不然直接返回缓存路径cc.FileUtils:getInstance():purgeCachedEntries()--重新加载require MODEL_NAME

顺带一题:lua脚本也是资源的一部分,从使用时候的文件路径也可以看出来,
和图片音频是同级的,只不过单独给了个文件夹而已。


资源更新

已经安装的apk中的资源,是没办法变动的,所以如果不能热更就变成了一锤子买卖,
出现问题只能重新安装新的apk来解决问题,成本大到离谱,比如显示出错了~,啧啧。

好在虽然我们包体本身资源没有办法修改,但是我们可以添加sd卡的读写权限,
然后再控制资源搜索的优先级,让其先去搜索sd卡,再搜索包体内的资源,
这样新下载的资源就会被优先读取,没有再去包体中搜索,从而实现“热更新”。


资源下载

cocos提供的AssetsManager,除了没有做文件完整性校验,功能基本够用了。
该做的处理cocos都给封装好了,使用起来非常简单。
基本用法

assetsManager:setDelegate = cc.AssetsManager:new(Zip_URL,                                                  Version_URL,                                                 cc.FileUtils:getInstance():getWritablePath())assetsManager:setDelegate(onError, cc.ASSETSMANAGER_PROTOCOL_ERROR )assetsManager:setDelegate(onProgress, cc.ASSETSMANAGER_PROTOCOL_PROGRESS)assetsManager:setDelegate(onSuccess, cc.ASSETSMANAGER_PROTOCOL_SUCCESS )assetsManager:checkUpdate()

我这里就直接简单粗暴的用了可写路径,没什么毛病,自带的代码示例里还用了createDir,
我感觉没什么必要,下载后如果是zip文件,会自行解压。
解压后文件所在路径:data/data/com.games.es(包名)/files/

如果root的话可以用adb shell 进入路径进行查看,别人的游戏也是一样(手动滑稽。
保证zip内的结构是 src 和 res 这样只要添加上搜索路径就可以了。

//我这边直接写在c++里了afileUtils->addSearchPath(fileUtils->getWritablePath() + "src", true);fileUtils->addSearchPath(fileUtils->getWritablePath() + "res", true);

资源打包

上面提到了下载zip文件,所以我们自然是用zip来做处理,cocos3.15给出了一个新的解决方案,
就是用单个文件的md5进行判断,如果有改动就下载知道本地md5列表和服务器的md5列表一致,
这样就省去了版本控制的麻烦,但是有好也有坏,
一是 http频繁创建有开销,
二是 多线程下载有线程数量限制,碎文件多时遇到瓶颈问题,
三是 文件读写效率问题,小文件拷贝和打包拷贝我想大家也深有体会,
最后 也是一个比较严重的问题就是长传速度较慢时候,资源没有全部传完,
   玩家这个时候进入游戏,可能会导致资源版本不一致,引发各种问题。

额,有点跑题,继续说资源打包,打包自然就是打变动的资源和新增的资源。
这个可以用自己做批处理,用比较成熟的git工具来处理,又或者肉眼处理法~
虽然都能解决问题,不过我这里稍微说一下前两种,

先科普一下几个跟时间有关的属性atime(Access time)   在读取文件或者执行文件时更改mtime(Modified time) 在写入文件时随文件内容的更改而更改ctime(Create time)   随 Inode 的内容更改而更改(写入文件、更改所有者、权限或链接设置等)

1.批处理:基本上就是通过递归遍历路径,读取文件的属性,判断mtime,拷贝出来进行打包。
比如上次打包的时间 2017-4-8,记录一下,下次打包时只要mtime大于这个时间拷贝出来。

2.git:这个就很方便了,不但显示直接而且还能显示文件差异,无敌是多么的寂寞~
主要就是git diff的命令,具体使用可以自行百度只显示文件名是 --name-status
批处理时可以先写入到一个临时文件,再从文件中读取。 git * > tmp.log

打包的话,我自己是比较喜欢用7z的命令行,因为支持的格式比较多。
zip也一样,命令格式也都大同小异,打出zip文件来就行了,可以用mx=9控制下压缩等级。

最后的最后自然就是上传到服务器供给玩家下载就行了。


总结

理论的部分基本都已经很全面了,我想有了这些我相信你也能写一个热更新了。
下一篇继续讲一下简单的版本控制和热更模块的自更新=。=
借用海贼王标准结尾~   To Be Continue!

See Again~
之前
真爱无价,欢迎打赏~
这里写图片描述

原创粉丝点击