从一次失败的换皮方案

之前做了一个用于教学的消除游戏Demo,主要是用于教美术,由于美术资源会有很多套,而且希望都能在手机上试玩体验。因此需要编写一个换皮打包的脚本,这样我就可以偷懒了!

1. 换皮方案

想到的简单方案是替换 Cocos Creator 构建输出的图片,这也是之前使用Cocos2d-x\lua\js时期使用的方法。

在实践此方案之前我还做了一番分析,当时信心满满,结果却掉进了坑里。

优点

先说一下我想到的该方案的优点,主要诱惑是不用多次构建,当时心里还乐滋滋的!

只构建一次资源,之后都在这个build出的资源基础上进行图片替换,如果是出web-mobile包直接将文件复制进去就完事。

如果是android、iOS替换完图片后要执行一次编译打包,使用Cocos Creator的命令行可以搞定。

难点

Cocos Creator 2.x构建输出的资源文件被更换为UUID命令,需要找到项目图片与构建图片文件名之间的对应关系,不过有之前折腾模块化子游戏时做过一个小插件,生成的资源地图文件可以搞定这个问题。

缺陷

此方案缺陷有很多:
1. 只能替换散图,项目中也不能使用自动图集
2. 自己生成图集也不行,因为图集的plist数据不好定位,找不到地方替换
3. 也不能替换其它数据文件

缺陷暂时处理不了只能人工绕道了,反正我只是为这个小demo项目解决问题,暂不考虑通用了。

2. 资源地图

要建立构建资源与项目资源的文件的对应关系,我之前做的插件,在构建完成时,会在项目temp目录下生成一个assets-map.json的文件,文件内容如下:

[
    {
        "nativePath": "res/raw-assets/ae/ae8e3d60-767e-493b-8a4d-6b564e7ecab0.png",
        "url": "main menu/back icon.png/back icon"
    },
    {
        "nativePath": "res/raw-assets/5d/5de7dc2b-df4c-404d-9f68-d799da224356.png",
        "url": "main menu/eject_btn.png/eject_btn"
    },
    {
        "nativePath": "res/raw-assets/03/038a47ce-d322-4654-a80d-0419c739168f.png",
        "url": "main menu/help_btn.png/help_btn"
    },
    {
        "nativePath": "res/raw-assets/a9/a91e438f-38c3-4cc9-9f86-3138b2afdafa.png",
        "url": "main menu/next_scene.png/next_scene"
    },
    {
        "nativePath": "res/raw-assets/68/68a612ed-3e86-43c2-8883-535bc7711af4.png",
        "url": "main menu/prev_scene.png/prev_scene"
    }
    ...
]

上面JSON数组中,每个元素的nativePath字段是构建文件路径,以可看到构建输出的uuid文件名,url字段是项目assets目录下的文件。

有了这个映射地图文件,就可以定位到构建资源进行文件替换了,大概流程如下:
1. 遍历某套皮肤目录中的jpg、png文件,并拿到assets-map.json中查找是否存在对应的url。
2. 存在url,取出nativePath字段,将皮肤目录中遍历时的当前文件复制到nativePath

当然,在过程中还需要拼接好完整路径,皮肤文件的路径要与项目匹配、图片尺寸要一致等,在此就不多说了。

3. 杯具产生

脚本编写好了,将换皮后的游戏在浏览器中尝试一下,见下图:

image.png

图中上半部分是游戏在编辑器中的效果,下半部分是资源替换后的运行效果,杯具了!
替换进去的图标被裁切了一部分!两套图片在尺寸上是一样的规格,为什么会这样呢?

将要替换的文件直接放从Cocos Creator项目assets目录,发现图片的meta文件有变化:

image.png

变化的内容正是图片SpriteFrame的属性,原始版本的图片透明区要大一些,约束框要小一点,替换资源的透明区要小一些约束框要大一点,构建资源虽然更新了图片,但SpriteFrame没更新,因此出现图片被裁切问题!

4. 结语

问题知道了,此路暂时不通,只好把图片导入Cocos Creator项目,还是走重新构编译的路子。

虽然方案失败了,还是想刨点有价值的东西,如果你对生成的assets-map文件感兴趣可以在公众号中回复:assets-map资源地图获取该插件。

使用方法:
1. 将插件放入项目package目录
2. build项目等待完成
3. 打开项目temp目录,会发现一个assets-map.json文件。


感谢关注「奎特尔星球」公众号,欢迎大家来稿,愿我们一起成长!