1445506370681719.jpg

  节奏大师是一款国民级的音乐游戏,写这篇文章的时候刚好是节奏大师三周年生日,2012年5月25日节奏大师首次发布,就吸引了众多的玩家,时隔一年多,节奏大师作为第三个登陆微信平台的腾讯自研游戏,刚上线就积累了非常多的用户。随着用户数的不断剧增,再加上当初手机游戏开发不够成熟,一些问题隐患也在上线后慢慢的暴露出来了。
  节奏大师是款国民级的音乐游戏,所以最早在客户端这一侧对它性能基线就设置的非常低,也就是要让游戏能够运行在各种设备上,不管是高端的还是低端的,需要保证在低端机上玩也不会出现过多的崩溃现象。
  另外客户端这一侧还得保证游戏的核心体验(也就是打歌)必须流畅,最关键的节奏大师的核心玩法是绝对不能出现有帧频不稳定的现象,也就是所谓的“突然卡一下”,因为只要一卡,对玩家的这种极致体验会带来非常不爽的感觉。经过一些测试,如果游戏帧速到了50以下,就会影响到核心体验,它不像其他类型的游戏,比如SLG这种类型的,中间卡一下不会有什么大碍。
  当初上线一段时间后,节奏大师出现了一个最严重的问题,就是内存,游戏启动以后常驻内存非常高,内存有问题,会带来各种隐患,比如会增加crash率,会影响到CPU的运行效率等等。经过开发的一系列排查,定位到一块地方,就是UI贴图资源占用过多。
  节奏大师的UI贴图资源主要用在以下几个地方:

  • UI显示,也就是平时看到的按钮、面板等图片资源;
  • 打歌时候的Note资源,特效资源等;
    根据测试,发现内存占用情况如下表:

1445506663248426.jpg

  这样看,还可能看不出什么问题,继续跟踪,发现在启动游戏后,进入主界面,发现内存就有100M左右,然后不停的切换界面,内存几乎保持不变,然后开始打歌游戏,内存会略有上涨,然后再退出打歌,发现内存却没有什么改变。
  节奏大师的UI是环形结构的,也就是每个UI都是独占的,当从这个UI切换到另一个UI,之前那个界面其实就可以从内存中销毁的,而从上面的测试结果来看,貌似是没有销毁这一回事,一上来内存就偏大,界面切换内存也不会有啥变化。另外我们也找到了目前UI图集的组织关系,如下图所示:

1445506866139184.jpg

  从上面可以看出,每个UI引用了多张贴图,也就是UI跟贴图之间没有任何的对应关系,乱糟糟的没有规划可言。所以这个也印证了上面的内存现象。
  目前这种UI组织架构会带来很严重问题:

  • 后续开发会有隐患,内存得不到控制,增加crash率,节奏大师是用户数非常多的项目,低端机有风险,对产品本身伤害很大
  • 引擎不成熟,没考虑图集释放,UI关闭的时候没有释放贴图的逻辑;
  • 工具端操作繁琐UI;
  • UI引用关系太复杂了,已经控制不下去了,以前都是美术随便照一张大图把小图放进去,手工切割sprite也非常不精确,有误差。

  针对上面的问题,主要从以下几个方面来解决:

  • 重新整理所有的Atlas图集,每个UI只有单一的图集与之对应;
  • 整理出公共的Atlas图集;
  • 修改所有的UI文件,将里面的sprite重定向到最新的sprite;

  具体的步骤如下:
  1. 切割原始的大贴图,将它们拆分成每张小图,其实这些小图就是美术当时做出来的;
  2. 扫描原始的UI文件,将每个UI用到的sprite,也就是小图,都收集到对应的文件夹下,也就是比如背包UI上用到的各张小图都归类到背包UI的文件夹下,这样就生成了多个目录,每个目录是对应的UI,目录下面都是下图;
  3. 扫描用到的公共sprite小图,将被UI用到了N(这个数字要反复测试调整)次的小图收集起来,把他们定义成公共Atlas图集;
  4. 将上面的各个UI目录,以及公共图集目录,重新打包成大图,生成最新的Atlas配置文件;
  5. 将原始的UI文件(这里的UI文件指的是UI的配置文件)里使用到的sprite配置重定向到最新的Atlas配置下的sprite。
  通过上面步骤,就把原先的贴图资源重新拆分合并,原先的UI配置重新统一修改,最终达到了这样的效果:

1445507087428036.jpg

  也就是首先每个Atlas配置只会对应一张贴图,每个UI只会使用自己的Atlas贴图以及公共贴图,所以理论上,在某个界面下,内存里的UI贴图资源最多只有两张1024*1024的图片,这样来看相对于之前,进入一个UI,要加载10来张贴图,这个方案是必须的也是必然的。
  这上面都是用工具处理的,在项目代码里,也需要做一些处理,这里就不展开说了。通过上面的修改,主要达成了几个目的:

  • 优化了美术同学的工作流程,美术同学只需要给程序这里出好每个小图就可以,不需要再去人为的拼大图以及人工划分sprite,对,你没看错,以前的大图不是用工具来打包的,是自己拼的,sprite信息也是自己手工切割的,下图所示:

1445507251607785.jpg

  里面的小矩形区域,是人为画的!!!!
  规范了程序开发的调用规范,每个UI的加载释放都通过断言去约束,确保发生一些不必要的错误;
  确保主玩法以外的独立场景,只有1-2张贴图资源,主玩法有6-7张贴图资源;
  最后看下优化后的结果:

1445507369613901.jpg

  也许好多人看到这里会觉得这种方案应该目前在每个项目都是这么用的,目前是非常普遍的做法,贴图资源用工具打包啊,每个UI由固定的独立的贴图去对应啊,但是因为节奏大师项目起步非常早,在手游领域这块摸索了很久,而且当初因为工具引擎端的不成熟,然后再加上人为的一些不严谨,导致了到最后问题被放大,差点无法控制。这个优化工作前后做了三个礼拜左右,涉及到所有的UI文件、UI贴图,工作量还是非常大的,最后贴几张当时优化中的一些成果:
  这是当初用工具扫描老UI的情况,是每个UI涉及到的贴图情况,还是相当吓人的。

1445507441177394.jpg

  这是当初写的工具,看起来有点乱。

1445507550820413.jpg