Write the Code. Change the World.

8月 06

关于cocos creator的总结的个人经验,性能优化包体缩小,小游戏的流程接入。这个总结目前只用到的是2D版本的,但是一些思想以及方法与3D也是可以通用的。

本文大概分为两个模块:

  1. 是小游戏的本身项目性能优化,项目开发中比较需要注意的点。
  2. 是关于微信,QQ,抖音,OPPO等小游戏的一些注意事项。

一.游戏立项开发时注意事项

1.在我们制作一款新游戏的时候,我们需要新建一个项目,(语言的话推荐的是TypeScript ,毕竟智能提示就真香了~)那么我们各种资源怎么分布,怎么分布的对未来项目开发的时候可以条理清晰,当我们开发到后期的时候,不必面对繁杂的各种资源无从下手。

首先,我们建立的项目 无论是代码还是各种资源都在assets下,我们需要在一开始的时候就区分好。

其中 将代码放到scrpts, 场景文件放到scenes,接下来是最重要的资源的放置,将有需要动态加载的资源放到resources中,不需要动态加载的资源放到res文件夹中。在此说明,在建立新项目时,建议先将资源全部放在res文件中,有需要动态加载的时候,在移入到resources文件夹下的相对应的文件夹中。在资源文件夹res或者resources文件夹中,需要在细分 anim:放置动画文件,font:放置字体,img:放置图片,otherRes:放置其他的一些资源例如json文件,sounds:放置声音音效,spine:放置龙骨动画。

特别说明:在img文件夹下对于图片的放置还应该以模块作为名字进行划分,进行模块化,对于可以公用的图片应该放到common中,公用的大图可以新建一个commonImg文件夹。

在对应的模块文件夹下,我们可以对该文件夹下加入cocos creator自带的自动图集配置功能(微信,头条等小游戏不一定适用自动图集配置,打包后会使得包体增加不少。),显著的减少DrawCall的数量。

在对应的模块文件夹建议可以再细分一个小的文件夹将大图放在模块文件夹下,将小图放置在再细分的文件夹中,该文件夹下,使用自动图集配置,这样做的好处是可以通过设置最大宽度的改变减少自动图集文件的大小,减少包体。具体方式如下图。

同样的,在scrtps文件中,也应该对应的放置各个模块的代码,具体的命名可以与资源下的文件夹同名,这样在后期的时候,能够有更好的对应。

如果能够在开发的初始阶段就这样的进行合理分配,那么到后期我们的项目也不会随着复杂度的增加而显得整个项目杂乱无章 无从下手,这对于自己本身的开发或者后续人员的接手开发都是更好接受的。

2.在游戏开发过程中,我们对于编辑器上的节点的寻找,一般有有两种方式,一种是在编辑器上挂载节点,一种方式是用cc.find()来寻找编辑器上的几点。我个人推荐大家使用的是挂载节点的方式。

为什么呢?我认为有两个原因。1.因为我们看cocos cretor的寻找模式,是一种冒泡式的寻找,cc.find会对你提供的路径进行每一个节点进行for循环查找节点,这相对来说更加的消耗性能,当你寻找的节点变多之后。耗能会更加明显(我的第一个游戏用的全是cc.find,就是玩久了耗电快会发烫~)2.当我们对节点进行名字更改或者位置转换的时候,就需要重新更改地址,这是一个非常麻烦的事情,会拖累我们的开发效率。

https://github.com/cocos-creator/engine/blob/8bf4522a6d43b53258219983aabd728909ce24ca/cocos2d/core/utils/find.js#L30

在这里给大家推荐一个插件,会自动的帮助我们挂载节点,更加简化了我们的工作,在这里对插件的作者表示感谢!https://forum.cocos.org/t/cocos-creator/91159

3.在游戏开发中,实例化预制体是一个不可避免的情况,在cocos creator2.0版本后,我们的预制体prefab支持了一个优化策略,用好这个优化策略,可以让你的游戏性能大大提升。

你项目中的预制体文件(.prefab)实际上就是一个 JSON 文件,存储着你的一些节点和组件的数据,当游戏运行并读取该预制体文件,引擎会通过这个 JSON 文件数据还原出预制体对象,这个 数据 -> 对象 的过程称为 “反序列化”。我们不会直接使用这个反序列化后的预制体对象,一般会调用 cc.instantiate 克隆该预制体对象生成一个 cc.Node 节点对象来使用,而这个过程称为 “实例化”。

而怎么样提高我们的实例化效率呢,主要就在我们对预制体实例化的优化策略选择上。

我这里简要说一下结论:
预制体如果不手动调整,则默认为 “自动调整”,三个策略的主要区别为:
自动调整:实例化时优先走普通实例化的流程,若实例化超过了 3 次,则在之后包括第 3 次会使用 JIT 优化实例化流程。
优化单次创建性能:实例化只走普通实例化流程。
优化多次创建性能:实例化只走 JIT 优化实例化流程。
具体的原理我们论坛的大佬已经有详细讲解了

解读 Cocos Creator 引擎:让实例化快 50% 的原理,“拖节点”性能会更好吗?

本篇为 “引擎的实例化”。 当布置好一个场景并在游戏中显示,或者使用预制体调用 cc.instantiate 实例化出节点时,我们可能有一些同样的疑问: 引擎是怎么样实例化的? ”优化多次创建“ 和 ”优化单次创建“ 的优化策略有什么不同? 在编辑器拖节点是不是要比 getChild 更好? 怎么样做,实例化时性能会更好? 相对上篇写 AssetManager…

4.关于资源释放的问题
在我们进行开发中 资源释放肯定是一个十分重要的地方,因为JS的本身机制的原因,资源释放不让内存增加一直是一个难点。
我主要讲一下我自己的理解,对各个情况的资源释放做的处理,如果这里讲的有错误,麻烦各位给我指正一下~
在场景切换过程中,要进行资源释放,可以通过勾选cocos creator本身自带的自动释放资源选项,就可以进行资源释放了(资源释放时,loadRes动态加载的资源需要手动releaseRes )

具体的描述,官方的引擎组在这个回答中有着比较完善的回复 我认为可以值得学习了解。

问官方个问题,场景切换和资源释放的正确方式 应该是个什么规则?
引用到的资源释 是不包括loadRes动态加载的资源把,这个还是得手动releaseRes 的把?

单场景的资源释放,经常会遇到资源释放的不彻底,或者过于彻底,将正在使用的资源也一起释放掉的问题,这主要是源于资源是互相依赖的,指定加载资源时,也会加载其所有依赖项。因此在处理资源释放时,需要考虑资源的依赖关系。 比如我们在释放prefab A 时 ,A中有引用了资源 1,2,3 同时在使用的prefab B引用了资源 2,3,4 那么如果将A的资源全部释放就会导致Prefab B 的资源报错。如果不将A资源释放,又会导致内存不断增高。因此我们需要通过官方API cc.loader.getDependsRecursively 接口来获取到资源的所有依赖项,包括依赖的依赖。这个接口可以让我们方便地获取到资源的依赖关系。通过在加载的时候的保存各个节点的资源来进行对比,对没有使用的资源进行释放,具体的分析 论坛的大佬的有个讲解十分不错,可以学习一下

Cocos Creator 中基于单场景的动态资源加载与释放技巧

动态加载的预制体,用destroy直接删就可以了吧。

创意小游戏《动物餐厅》技术总结以及现存问题反馈

最早接触cocos 是12年刚实习那会,依稀记得那时候cocos2d-x 的版本号还是1.x,一路走过来cocos已经陪伴我走过了8年风雨。很感谢cocos以及类似开源软件给我带来的长足技术进步,一直在社区里也是沉默寡言,基本只对bug讨论和feature感兴趣【可能因为时间关系,更多关注的是自己团队实际遇到的问题】 深感闭门造车的困境,终于趁着有半日的喘息,一股脑把《动物餐厅》开发到至今遇到的难点问题进行一次总结反馈,也算是对cocos社区的新一轮反馈与回馈 …

当然,如果游戏的复杂度不高,我们可以直接进行destory就可以了,creator会在某个时间节点对资源进行自动的释放。
5.对象池的使用在我们游戏开发过程中,想要提高游戏性能必不可少的一个步骤,对于游戏中一些出现频率高的节点,比如子弹,用对象池来处理再好不过了。
关于对象池的使用官网的文档说的已经十分详细,本文就不过多阐述了

https://docs.cocos.com/creator/manual/zh/scripting/pooling.html26

只在这里点出一个注意事项,在对象池中的对象放回对象池之前,要对该对象进行初始化还原,不然再取出的时候,还是之前的状态。

二.关于微信,QQ,抖音,OPPO等小游戏的一些注意事项,包体缩小,性能优化

Cocos creator 现在只支持的是微信, oppo ,vivo ,华为快游戏,小米快游戏,百度小游戏,qq轻游戏。我只说一下我有接触过的几种,分别是微信。字节跳动小游戏,qq小程序,oppo vivo。

先说一下各个平台的一些事项,以及感悟。最后总结一些方法。
1.微信小游戏是现在小游戏开发者中最广的, 也是最规范,平台最稳定的。相对于其他平台的bug也是最少的。对于小游戏领域有兴趣的朋友第一个可以尝试的就是微信小程序,现在个人开发者也能制作小游戏发布。微信的大小限制最开始的时候是4M,现在最新的已经扩展到了16M也就是主包4M最多允许有3个大小最大为4M的分包,cocos creator官方文档对于微信的接入和分包方法都有着详细的教程,大家想了解的可以去具体的看一下就了解了。

https://docs.cocos.com/creator/manual/zh/publish/publish-wechatgame.html16

微信需要特意提的两个地方是 1 Cocos Creator v2.2.1 及以上版本 提供了一个微信小游戏引擎插件,若玩家首次体验的游戏中启用了此插件,则所有同样启用此插件的游戏,都无需再次下载 Cocos Creator 引擎,只需直接使用公共插件库中的相同版本引擎,或者增量更新引擎即可。使用起来也非常方便,只需要在构建的地方勾选一下即可。

2是对于微信开放数据的使用,在开发过程中,我们使用到开发数据域大部分都是为了排行榜的功能,但是如果使用官方的方式,太占用主包的大小,因为开放数据域必须在主包,但是这个大小动不动就2M左右,十分影响。因此建议在没有使用到过于复杂的功能的时候可以用原生的方式来使用开放数据。具体的方法论坛大佬已经有贡献了,

开源微信小游戏排行榜代码示例程序(可直接使用)

最近好多提问微信小游戏排行榜的问题,个人项目中使用到了,现在把代码开源出来,欢迎有需要的同学进来看看,此示例中包含好友排行榜列表、群排行榜列表、上传得分、横向排行展示等功能,可直接嵌入到程序中使用,有JavaScript版本和TypeScript版本示例,有问题可留言反馈或进群交流(QQ群:805415449),拿走不谢。 码云代码地址:https://gitee.com/xwintop/wxGameRank…

https://forum.cocos.org/t/demo-api/64299
这里简单提供两个都是可以直接使用和二次开发自己想要的功能的。
2字节跳动小游戏,qq小程序
这虽然是两个平台 ,但是大致方式是差不多的,因此放在一起说。
目前cocos creator 虽然没有支持这两个平台,但是使用微信小游戏的构建方式,是可以在这两个平台上通用的,只需要不同平台的APPID以及相对应的API,值得一提的是,字节跳动小游戏与QQ小程序的API与微信小游戏的API是十分相似的,因此当大家如果在这两个平台遇到了问题,不妨去微信API看一下详细的解释,说不定会有惊喜哦。
字节跳动小游戏需要下载字节跳动开发者工具,上传游戏之后,可以选择在今日头条 ,抖音,西瓜视频等APP上发布,无需再额外的更改。需要注意的是相对其他平台,字节跳动小游戏需要在游戏中添加录屏功能,并要能分享。
具体有兴趣的同学 可以看一下文档
https://microapp.bytedance.com/dev/cn/mini-game/introduction/function-access-guide/record-share10
qq小程序要注意的点则是他们的开放数据域由于是没有cocos creator支持的,因此经常会报一些奇怪的错误,如果有遇到的,可以具体私信我,我也会给大家尽力解答的~
3.oppo vivo
如果说微信,字节,qq算是一个类型的api小游戏的话,那么oppo与vivo则是另一个体系的了(这个地方有咨询了我的同事,感谢她!)
** 接入VIVO版本流程

cocos creator 引擎版本低于 v2.1.3 不可分小包模式
1.1小包模式 部署一个远程服务器 存放编译出来的res文件,每次更改资源需要重新上传到服务器,然后把本地的res文件删除,使用命令行重新打包 在构建的qgame文件地址栏运行 cmd 命名提示符 输入 npm run build 编译完成后再输入npm run server 可生成二维码 命名行构建 默认是debug的签名

Vivo 官方文档
https://minigame.vivo.com.cn/documents/#/api/service/newaccount5

二维码生成
cocos creator 运行后没有反应 请用命令行生成 确保安装好环境 环境安装请参考
https://docs.cocos.com/creator/manual/zh/publish/publish-vivo-instant-games.html7

在构建的qgame文件地址栏运行 cmd 命令提示符 输入 npm run server 就会生成二维码
// 真机调试
启动chrome浏览器访问:
chrome浏览器调试用 Chrome 浏览器打开地址:chrome-devtools://devtools/bundled/inspector.html?v8only=true&ws={IP}:5086/00010002-0003-4004-8005-000600070008其中 {IP} 为 Android 设备的本地 IP,即可进行调试,手机IP可以从设置中的wifi模块获取

4.资源远程加载问题
Vivo目前暂不支持直接加载网络资源 需要先调用下载方法qg.download() 再使用转存qg.copyFile() 再调用方法去加载或者读取存储好的本地文件
qg.download({
url: ‘url’,
success: function (data) { //data 为.txt 文件 格式要自己去转
console.log(handling success, tempFilePath = ${data.tempFilePath})
},
fail: function (data, code) {
console.log(handling fail, code = ${code})
}
});
// 接口如下
https://minigame.vivo.com.cn/documents/#/api/network/upload-download?id=%e4%b8%8a%e4%bc%a0%e4%b8%8b%e8%bd%bd3

5.关于登录时提示游戏奔溃,但是关闭提示又不影响游戏进程,照常能玩游戏,大部分是声音导致的问题,尽量不要使用playMusic(), stopMusic(),cocos声音模块底层有个status为-1 导致的奔溃,可改为play()。至于原因不知道为啥。

6.登录流程接入
走qg.login 需要快应用版本1053+ 并且根据token 通过登录token获取用户信息 qg.getSystemInfoSync() 返回没有openId 这个接口需要与服务端对接,可考虑是否有必要走复杂登录流程 https://minigame.vivo.com.cn/documents/#/api/service/newaccount5
如果只接简单的登录流程,qg.authorize授权 根据获取拿到token 通过接口 qg.getProfile()获取用户信息 (注意:qg.login获取到token在这个接口拿不到任何信息);
https://minigame.vivo.com.cn/documents/#/api/service/account?id=%e8%b4%a6%e5%8f%b7

Oppo的接入方式与vivo其实是几乎一致的,因此oppo的接入流程中就多写一些注意事项

** ## OPPO版本接入流程**

官网文档 https://cdofs.oppomobile.com/cdo-activity/static/201810/26/quickgame/documentation/feature/loading.html4

// 登录流程
qg.login(object)
持最低平台版本号’1040′ (minPlatformVersion>=’1040′)
没有授权框,手机账号有登录oppo账号会自动授权,没有登录oppo账号会有oppo提供的一个弹窗 登录账号或者游客登录的弹窗

特别注意:有部分手机返回的 errCode:999 官网无解释,问过oppo对接人员,导致原因是oppo后台查不到这个账号信息,至于有账号为啥查不到信息对接人员未解释,所有可做少数的情况下可做一个游客账号登录。

// 特别说明:
qg.setLoadingProgress(object)支持最低平台版本号’1031′
设置游戏加载进度页面(该功能必须接入,否则会因为未接入,导致游戏加载页进度条缺失而被测试打回)
授权成功 loading界面传入进度值即可
qg.setLoadingProgress({
progress: 50 });
进度值加载完成 调用该接口变可
qg.loadingComplete({
complete:function(res){}});

到此 整个登录流程就算接完了

真机调试
chrome-devtools://devtools/bundled/inspector.html?v8only=true&ws=10.102.227.164:12345/00010002-0003-4004-8005-000600070008 ip地址改成手机上的ip地址即可 12345 无调试换成12346即可

//////// 广告接入
Oppo广告
注意 1051版本以上不需要进行广告初始化,其他版本需要进行初始化否则可能会导致拉取不到广告 —> qg.initAdService(object)
附上广告常见的问题
https://cdofs.oppomobile.com/cdo-activity/static/201810/26/quickgame/documentation/ad/question.html4

Oppo对广告展示有限制 1.banner 用户手动关闭5次后则当天不可再显示 2.插屏展示 每天不超过8次,前面6次间隔不得超过60s 后面间隔需要30s以上。
开屏广告 无需我们技术接入
Banner 广告 有个需要注意点 banner 版本号’1051 可设置大小,低于1051版本 不可设置大小,且位置无法改变一直在下方正中。竖版游戏宽度要和适配手机大小
激励广告 无特别点
插屏广告 无特别点
原生广告 可有多个原生广告位1. 大小须自设 2.有可能会拉取到支付宝的广告,支付宝广告图片的url涉及安全 无法加载,此时有多个原生可拉取其他的原生。3原生广告类型较多

另外: 错误码 20003 errMsg 为 ‘ad list is null’,先检查是否有再onLoad调用show,如果写法无误,官方人员给了另外一个说明,广告填充不足,正常情况不是每次拉取都会有填充。

三小游戏的通用优化

包体缩小小游戏常用的几种方式 有:1.对于图片的大小,音乐音效的大小进行合理的压缩,在尽量不损失像素画面的情况下,进行压缩图片,效果特别的显著,具体的插件的话,cocos creator拓展商店中就有哦。

2.引擎的无用功能去除
Cocos creator引擎中含有着各式各样的功能与模块,但是并不是每一个模块都是我们有使用到的,因此我们可以将我们没有使用到的模块不进行打包进引擎文件中,从而达到减少包体的效果。

比如我们的游戏中没有使用到LabelOutLine这个模块,那么我们就可以不勾选它,这样它就不会被打包到我们的引擎文件中了。
3.将一些关卡配置json文件之类的可以放置到CDN上下载
4.场景背景图可以利用小图进行九宫格拉伸,达到用小资源实现的效果。
性能优化
1.小游戏音效卡顿优化
在微信小游戏里,频繁的 play 音效,会造成一定卡顿。比如当子弹撞击到敌人的时候,或者金币拾起的时候。
这个时候可以将短时间重复播放的音效合成一个,来循环播放,或者直接单音循环播放也可以起到优化的效果。在碰撞或者动画结束的时候,暂停(pause)音效播放即可,下次只要resume 就好。或者可以设置在几秒之内重复收到同样的音效不执行。
总之就是避免频繁的 执行 play。
2.大量重复创建的节点一定要使用节点池
各个小游戏平台的性能有限,因此有需要大量重复创建的,一定要使用对象池,可以显著提高游戏性能。
3.少对节点进行频繁的active切换
频繁的进行active切换也是比较消耗性能的,因此如果有需要的话可以对节点的透明度Opacity进行0与255之间的切换可以达到同样的效果(或者直接移除屏幕外)。
4.首屏加载速度优化
小游戏的首屏加载速度影响还是比较大的,一般来说3秒以内算是比较好的,3-5秒是正常情况,7秒之后的则会导致游戏的流失率大大的增加,因此,我们在首屏的时候最好不要加载过多的东西。针对这个问题,论坛中各位大佬也有着很多方法可以学习一下

官方教程:通过加载界面优化微信小游戏启动速度

原先进入微信小游戏的时候会直接加载游戏场景,首包过大会导致游戏启动慢。该范例中,在进入微信小游戏之前加入了一个 loading 界面,这样子在微信小游戏首包中只需要放入 loading 界面所需要的资源,首包将会减少到最小,微信小游戏的启动速度也会变快。 操作步骤: 建立一个 HelloWorld 工程 在项目目录下建立 build-templates/wechatgame/src/ 目录 在 src 目录中添加一个 loading-scene.js 脚本 在这个脚本中创建一个

5.延迟加载资源,对于打开某些界面速度有提升。
6.竖屏游戏适配
这个主要是针对IOS机型,在iphoneX及以上的机型,由于屏幕顶部有黑边,会导致部分的节点会被黑边遮挡住,造成与原有的设计效果不符的情况,因此我们可以在编辑器创建的时候,创建一个top的空节点,将需要放在头部的图片,放在top节点下,由于top已经绑定了widget,因此top中的子节点也无需在添加widget。

当我们在进入游戏的时候可以通过获取机型来判断是否iphoneX及以上,如果是的话则对top的子节点进行统一的下移。具体代码可以如下图

7.对于文字过多的情况的使用
在同时渲染的文字过多的情况下,在label中尽量少使用shrink,因为在某些情况下,一个label的shrink就可能造成成吨的卡顿。
对于单个界面创建时,如果存在大量的文本内容,但是文本内容的字符重复较多时(字符数量 < 文本数量)可以采用CHAR模式进行字符缓存,减少字符纹理的创建。如果系统文本数量太多,部分采用BMFont或者第三方字体解决方案的同时,其他系统文本可以分帧延迟创建,尽量避免同一事件创建大量的文本数量。
## 最后
在学习cocos creator的过程中,我遇到了很多热心的同学,我们的论坛氛围很好,很多同学热心的分享经验和指导网络对面的我们,教会了我很多东西,如果没有这么多热心同学的分享,我可能早就已经因为遇到解决不了的问题而放弃了这个行业了。
在我第一次的学习中,我甚至因为进度太差而被公司开除了,但是我也坚持下来了,也多亏了大家的分享和指导,我才能不断的学习(虽然还是有很多的疑问)。在这里我要对@谁睡觉叫@王哲 以及各位热心分享经验的大佬的表示感谢,让我学习了很多,让我在最不懂的时候得到了进步放心。希望以后能够共同的进步,谢谢大家!
游戏开发这个行业,永远有不了解的地方,永远有需要学习的地方,开发就是一个不断学习的工作,梦想不抛弃苦心追求的人~与君共勉。

文章来源

https://forum.cocos.org/t/creator/94747

更多

https://www.byjth.com/

发表评论

电子邮件地址不会被公开。 必填项已用*标注