昨天刚发布的Cocos Creator v1.6正式版你们下载升级了吗?引擎团队潜心修炼了三个月的大作,终于赶在本月新鲜出炉。一起来看看有哪些值得期待的亮点功能吧!
v1.6 新版本中,我们针对 HTML5 游戏的资源索引机制又进行了一轮优化,一方面大幅减小了资源索引文件的体积,另一方面在构建流程中为生成的资源文件名加入了版本号标识,使得终端用户能够正确更新所有的资源缓存。
要说明这次的优化,就先要介绍 `settings.js` 资源索引文件。这个文件以 JSON 的格式列出了项目构建后需要使用的所有资源,包括图片、声音、字体、场景、预制等等。可以认为这是资源数据库的索引 map,当我们需要在运行时加载和引用任何资源时,都需要从 `settings.js` 定义的表中查找。
场景和动画文件里引用的任何资源,其默认的索引形式都是该资源的 uuid(通用唯一识别码)。资源的 uuid 在首次导入资源时会自动由随机算法生成,共用 32 位字符,几乎可以认为不可能有两个不同的资源使用相同的 uuid,因此我们使用 32 位 uuid 作为资源的唯一标识。
`settings.js` 里索引资源的时候有两种方式,一种是原始资源,不包含资源描述文件,比如贴图、声音文件等:
```json
"58b3a98d-fb96-461f-9e82-8d1f79931f25": [
"textures/background.jpg",
"cc.Texture2D"
]
```
第二种方式是包含资源描述信息的场景、预制或 spriteFrame 资源,比如我们常用的 UI 九宫格切分,其切分信息就是存在资源描述文件中的,比如:
```json
"5ae5fc98-59fc-46aa-a111-ea45a3736d35":[
"textures/background.jpg/background",
"cc.SpriteFrame"
]
```
当加载包含这个资源的场景时(通过 cc.Sprite 组件中的 spriteFrame 属性),首先会找到构建目录下的 `res/import/5a/5ae5fc98-59fc-46aa-a111-ea45a3736d35.json` 文件,获取其资源描述信息。然后在这份文件中读到
```json
"texture":"58b3a98d-fb96-461f-9e82-8d1f79931f25"
```
这样的原始贴图信息,再通过查询 `settings.js` 中相应 uuid 所指向的资源文件路径来加载贴图。
了解了资源索引的原理,我们不难理解使用 32 位 uuid 来作为资源唯一标识的必要性,然而很多开发者在制作 HTML5 游戏时面临首包大小优化的巨大压力,在资源量巨大的游戏中 `settings.js` 的文件尺寸很容易上涨到 MB 的量级,而其中大部分的文件内容都被 32 位的 uuid 所充满了。
在 v1.6 版本中,我们选择了兼顾唯一标识安全性和体积的方案,在构建阶段将所有资源的 uuid 进行 base64 无损计算,由 32 位 uuid(实际 36 个字符)压缩成 22 位的 base64 字符串。对于只有在构建阶段才会生成的合并资源(如自动图集、场景合并资源描述文件等),只取 uuid 的前 9 位。这样处理后的资源索引就会变成这样:
```json
"rawAssets": {
"assets": {
"22TOboDjJDCpgHlFL8dprJ": [
"res/atlas/emoji.png",
"cc.Texture2D"
],
"834FFm1hFFKqwvTL9cPVoG": [
"res/atlas/sheep.png",
"cc.Texture2D"
]
}
},
"packedAssets": {
"0136a318c": [
"08MO6CARZIxILgiXhPXkoE",
"7cy3hPfFFKC6We6V2kDzAT",
"a7F3ZqgbtMZ7QXau4AW1JU"
],
"013a50185": [
"04Z0Q+b7hNe6NPV7PlwUn7",
"f2QMPqvQFB37JJaVB15KSv"
]
}
```
同时,我们还针对同一份资源在多个场景中出现的情况,对其 uuid 索引进行了合并,这些反复出现的资源会被放在一个数组中,并通过数组的序号来索引。
经测试,压缩后的资源索引原始文件可以比之前的版本体积下降 40%~50%,经过 gzip 压缩后的体积也能下降 15% 以上。
对 H5 游戏开发者来说,有效利用浏览器的缓存机制,避免用户重复下载资源,并且在更新游戏资源时确保更新缓存的资源版本是非常重要的。我们在这个版本的构建发布面板里增加了 **md5 cache** 构建选项,勾选后会在构建时为所有资源文件名增加该文件的 md5 码。