这边文章说一下cocos2d-x中游戏热更和导入包相关的知识。

打包

一般将cocos2d-x部分和原生分开打包。cocos2d-x打包完成后,放在安卓项目assets目录下打apk包。
app.apk
├──assets
├──src
└──res

启动

在安卓系统上,一个cocos游戏启动时,会加载assets/src/main.lua文件,需要热更新时,需要导入热更新文件目录下的代码和资源,用到cc.FileUtils,将这个目录添加到搜索目录,require的时候cocos就知道去哪里找更新文件。

1
2
3
4
5
6
-- fileUtils:getWritablePath()获取的是 /data/data/packageName/ 目录
updatePath = fileUtils:getWritablePath().. "xxx" -- 自定义文件夹

fileUtils:addSearchPath(updatePath)
fileUtils:addSearchPath(updatePath.."src/")
fileUtils:addSearchPath(updatePath.."res/")

文件更新

cocos2d-x的热更新是通过cc.AssetsManagerEx实现的,打cocos包的时候生成一个json文件,记录每个文件的路径和md5。cc.AssetsManagerEx通过对比两个json文件中的内容,去下载需要更新的文件。
project.manifest文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{

"packageUrl" : "",

"remoteVersionUrl" : "http://xxx.com/version.manifest",

"remoteManifestUrl" : "http://xxx.com/project.manifest",

"version" : "2.0.1",

"engineVersion" : "2.0.1",
"assets":{
"res/audio/bg.mp3" : {
"md5" : "15b0e4045ebaca9f2e56149e9d28e390"
},
...
...
}
}

内存相关

cocos2d-x中,把一个lua文件加载到内存中,用的是require。一个文件被require之后,保存在package.loaded表里,当再次require的时候,只将对象返回,并不会重新加载文件。因此在require后文件发生改变,想重新加载文件,需要在package.loaded里将这个值设为nil,再require就是新的了。
做游戏更新时会需要这个知识点。

1
2
3
4
5
6
7
1. 更新前
require("app.Version") -- v1.0
2. 更新后
require("app.Version") -- v1.0

package.loaded["app.Version"] = nil
require(app.Version) -- v2.0