7. 耗电优化
游戏耗电和游戏卡并无必然联系,有些游戏在某些设备上虽然运行很流畅,但发现耗电很厉害,玩了不到半个小时,电量已经出现警报。游戏耗电的原因主要是因为:CPU占用普遍高,内存操作频繁,磁盘IO频繁,渲染消耗普遍高,导致带宽负载和GPU消耗高。前面介绍的章节基本可以降低耗电,也是优化耗电的必要措施。尤其是以下章节对耗电优化更明显:
2. 资源优化
3.3 限帧法
3.4 主次法
3.6 引擎模块优化
4 渲染优化
5.4 控制GC
6. 5 IO优化
除了以上章节,还可以用动态调整帧率和画质的优化技法。
7.1 动态调整限帧
游戏逻辑通常可以获取当前设备的电量,若可以,则每隔一段时间获取一次电量信息,可以统计出单位耗电量,如果发现单位时间耗电量过高,而游戏帧率又很高(比如大于50),可以主动降低帧率(比如30)。
7.2 动态调整画质
做法跟动态限帧类似,只是调整的是画质等级,而不是帧率。当然也可以一起结合使用。
8. 网络优化
网络优化的目的是让网络包更小,响应更及时,消耗更少流量,不卡主线程。
8.1 减少无用字段
网络包中通常包含了很多信息,诸如角色位置,朝向,状态等。如果是2.5D游戏,则位置z分量可以弃掉;朝向只在xz平面上,所以只需要发送RotationY。通过这种减少无用字段,可以一定程度上降低网络包大小。
8.2 降低字段精度
通常逻辑里的很多信息都是4字节,包括角色位置,朝向,技能或Buff信息等。但很多时候,这些信息不可能达到4字节数的最大值,可以压缩至2字节甚至1字节。比如,同样是位置,场景的尺寸通常在2字节数的表示范围内(-32512~32512),可以将位置的x/y/z压缩至2字节发送。同样地,朝向RotationY可以2字节表示。
8.3 避免重复发送
游戏网络模块须有效限制部分协议在短时间内重复发送,例如玩家在短时间内按了很多次抽奖按钮。所以需要一种机制来限制。比如可以在网络协议定义时,加个标记,表明该协议不能在某个时间段内重复发送。
8.4 网络异步化
开辟独立的线程处理收发网络协议包,是游戏常见的优化手段,可以避免与主线程相互等待。
8.5 压缩无效字节
压缩无效字节是指通过一种方式剔除每个字段内高位全0的数据。比如角色等级50,如果用int32表示,是00000000 00000000 00000000 00110010,高位3个字节全是0,可以压缩至1字节。这里有一种压缩字节的方法,跟utf8编码方式类似。
utf8的编码方式(x代表有效位):
1字节(最大有效位7) :0xxxxxxx
2字节(最大有效位11):110xxxxx 10xxxxxx
3字节(最大有效位16):1110xxxx 10xxxxxx 10xxxxxx
4字节(最大有效位21):11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5字节(最大有效位26):111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6字节(最大有效位31):1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
比如角色等级50,有效位是6,用1字节便够了,压缩成00110010(红色是压缩位标记)。如果是数字1000,int32表示为00000000 00000000 00000011 11101000,有效位是10,需要2字节编码,压缩后是11001111 10101000(红色是压缩位标记)。采用这种压缩方式,普遍可以用1~2个字节取代4字节数据,压缩效果比较明显。
8.6 压缩协议包
8.5压缩的是字段内数据,每个数据包其实有很多相同的数字,可以用目前主流的压缩方法再对网络包做一次压缩。游戏最常用的压缩方法是zlib开源库,还可以用lz4方法。具体实现可以另外寻资料,这里不详述。