Cocos 公众号近半年来邀请了多位优秀的开发者进行案例分享,比如梦加《足球弹弹乐》、华夏乐游《欢乐枪战》、腾讯《乱斗之星》等,受到很多读者的喜爱。基于此,我们决定开设这个「技术派」专栏,今后将不定期邀请知名的游戏制作者,带来他们实战项目的开发技术和制作经验。
来自杭州电魂网络的主程蓝图,接受了 Cocos 的邀请,将在「技术派」专栏第一期,为大家带来《野蛮人大作战 H5》项目从开发到上线的经验分享。
《野蛮人大作战》是由电魂旗下 BBQ 工作室自主研发的像素风 io 英雄对战手游,一直是同类型游戏中品质领先的产品,游戏一上线便以新颖独特的玩法、魔性趣味的风格吸引了大量玩家。开发团队以市场需求和用户体验为导向,不断在进行游戏玩法与技术的革命。而基于对自创 IP 的再开发,《野蛮人大作战 H5》近日已正式上线,依托于电魂多年来对于竞技类产品的开发经验,结合 H5 的轻量级特性,相信《野蛮人大作战 H5》能够取得不错的成绩。
作者:蓝图
职业:程序主管
公司:杭州电魂
概述
《野蛮人大作战 H5》是一款实时竞技 io 类游戏,战斗内( websocket )采用帧同步模式,由服务端对玩家的帧协议进行包装和转发,客户端进行接收和处理战斗逻辑。
开发
1.工具
客户端:Cocos Creator , JavaScript
服务器:Java , C++ , 运行环境 Linux
第三方库: Protobuf C++ 版本 2.6.1 JS版本 6.8.4
2.架构
简单说下架构:
客户端这块需要把代码上传微信服务器,如果包体和资源控制在 4M 以内的话,就不需要 CDN,我们游戏资源包远超过 4M,所以代码放在微信服务器,资源放在CDN。
服务器分两块:
一个是逻辑服务器(LogicServer),逻辑服务器负责局外系统的交互;
一个帧同步服务器(RaceServer),负责整个战斗中的数据转发。
从微信中打开游戏,会获取到微信账号之类的信息,去逻辑服务器去二次验证,验证通过后,进入 LogicServer,获取到游戏中相应的数据信息,比如角色信息,背包信息等。
玩家点击开始战斗的时候,客户端去连接 RaceServer。
3.开发过程
开始接到需求是,要把野蛮人 App 转做H5,由于人手原因(当时能腾出手的只有 2 个人),资源基本用的是 APP 的资源,好的是 APP 用的是 Cocos2d-x 开发,UI 可以通过工具转换成 Cocos Creator 所支持的格式,动画用的是 Cocos2d-x 的动画编辑器,无法转换,前期美术策划不参与,为了减少工作量,通过和 Cocos 官方开发人员商量,官方同意帮我们开发工具把 2d-x 格式的动画转换成 Creator 所支持的格式,这里非常感谢 Cocos Creator 开发人员 Knox 同学,帮了我们很大的忙,减少了不少工作量。https://github.com/knoxHuang/cstudio-anim-import
2. 转表工具,原来转表工具不支持 json 格式,找到公司公共部门帮实现了支持 json 格式的转表工具。
3. 工具齐全,搞起搞起,加班加点一个月左右的时间完成了单局部分,就是可以看到角色 AI,可以在场景中互相砍杀,在这过程中遇到最多的问题,就是 js 的引用问题。比如:
var obj = {x:0,y:0};
var obj2 = obj;
本意是想复制一个对象,但是 js 中对象赋值都是引用,只要操作 obj2 就会导致 obj 对象中的数据变化,这和 C++ 不太一样(我们多是从 C++ 转过来),当逻辑复杂的时候不是很好找。
4. 网络版本。网络部分采用 websocket,微信平台强制要求 wss,由于加解密会导致网络部分延迟提高,协议部分采用 protobufjs,pb 通过二进制传输,要比 json 流量小,版本采用的是 6.8.4,微信平台不允许 eval 或 new Fuction 动态代码的执行,所以不能通过加载 .poto 文件,只能将 poto 文件转换成静态的 js 代码( 5.0 版本是可以加载 poto 文件的,但是效率上没有 6.8 版本高),注意,protobufjs 默认是不支持 64 位整数的,如果需要的话,自己要改动,把 long.js 文件打包进去。
网络消息的接收
网络消息的发送
网络同步选择为帧同步。
帧同步优点:
1.网络流量小,只需要转发玩家操作指令
2.服务器压力小,服务只需要转发,没有啥逻辑运算,承载量大
帧同步缺点:
1. 作弊比较容易,因为逻辑都在客户端,可以修改本地数据。
2. 重连,重连过程需要把前面的逻辑都跑完,如果单局时间长的话,追帧需要一定的时间。
帧同步是需要客户端严格的按照一定的指令执行,客户单部分分成三部分:
1.客户端渲染部分
2.网络部分
3.逻辑部分
这里简单说下逻辑结构:
逻辑结构主要是由技能(这里的技能并非角色释放的技能,可以理解为提供给策划调用的接口)和动作(具体执行的接口,比如创建单位,修改坐标,播放音效,移动,延迟执行等各种驱动角色的接口)构成,程序主要实现各种接口,策划通过配表的方式,表格可以控制各种参数,添加各种技能,技能调用动作,动作里也可以嵌套技能,可以灵活的创建游戏逻辑。
这里的效果就是调用对应的动作
图中两种颜色的线条:
蓝色代表单机版,单机中客户单需要把指令发送到指令队列中,逻辑从指令队列中取出相应的指令执行逻辑,把执行结果通过事件触发告诉客户端,客户端按照逻辑的结果执行,比如逻辑中添加一个单位,客户端中就创建一个单位模型。
绿色代表网络版,网络版本需要把玩家的操作指令发送给服务器,服务器收到指令后,把指令保存到服务器单局队列中(追帧或观看需要用到),然后广播转发出去,客户端收到网络过来的数据包,发送到指令队列中。
帧同步不能使用系统的随机函数,需要自己封装一个随机算法,指定随机种子,保证每个设备在相同帧数下,随机出来的数是一样的。
《野蛮人大作战 H5 》在逻辑中用到 box2d 物理库,主要实现角色的移动、碰撞等功能,在这里对 box2d 库的一些数学函数的一点小改动,为了防止出现精度误差导致不同步和效率。
又经过一个月左右的开发联调,联网部分也完成,可以两个人在游戏中 PK。这个过程中也遇到不少问题,貌似不同步只遇到过一个问题,是在网络收数据的时候指令顺序问题,导致不同步,解决后,再没出现过不同步,js 在这一块要比 C++ 方便的多,C++ 中如果变量未初始化,就会出现不同步,js 没初始化,所有的都是 undefine,都一样,就不会出现不同步了。
似乎没啥问题了,整个战斗流程都走起来了,后边就是堆系统,开始测试性能了。在 PC 上一切都正常,用 iphone7 试了下,也能跑得动,用 Android 手机测试,发现问题很严重,还用的是小米 5s 821,游戏画面一卡一卡的,和放幻灯片一样,因此可见 iOS 和 Android、 APP 和 H5 之间的性能相差甚大啊。
优化
我们团队端游出身,没有啥 H5 经验,咨询 Cocos 团队开发人员,给到了一些建议,当时单局内 drawcall 最高的在 180 左右,我们从以下几点做了优化:
1.合图
原有资源都是碎图,角色部分策划同学在导出的时候用的大图 1024,UI 部分用的 Creator 自带的自动合图工具。
2.固定字体符号用 bmpfront,单局中出现的字母,数字,一些固定符号都用了 bmpfont 代替
3.节点池,客户单创建单位都采取了节点池,避免重复的创建节点,据说 cc.instantiate 比较费。
4.减少一些效果,shader 用到的变色,描边,动态阴影等效果去掉。
5.减少 UI 刷新频率,比如单局中的排行榜,原来是每帧都在刷,其实是没必要的,1 秒刷一次就可以了,还有不少类似的都可以优化,如果单位比较多的话,节点的 zIndex 也是比较费的,也改为 1 秒钟刷一次。
6.优化逻辑,其实这个是一个大头,当时采用的 app 的配置文件,我们对表格的优化,减少了不必要的调用,逻辑这块比较复杂,就把逻辑中的添加技能(不是真正的技能,上文已经解释过),在没有优化之前,应该每秒钟执行 2000 左右的添加技能,优化过后,减少了几百,还是太多,通过和策划商量,通过各种优化,最终把技能降到 170 左右。
7.逻辑中比较频繁的对象创建,原来所有的对象都用的 cc.Class,最终都采用原生 js 的方法。
8.减少场景物。
9.减少太复杂的技能。
10.根据屏幕大小渲染,屏幕外的单位设置节点 active 为 false。
经过各种优化 drawcall 最终优化到了 100 以内,在 Android 一些中配以上的机器上可以非常流畅的运行了,但是在一些比较低配置的机器上还是有点卡。
那段时间,Cocos Creator 2.0 诞生了,据官方说 2.0 版本性能大幅度提升,我们拿到 了内部版本,经过测试,性能提升确实很大,原来在一个红米 2s 上跑只有 10 几帧,用 2.0 跑了下,基本都在 28 帧以上了,性能翻倍。
在这里非常得感谢 Cocos 官方技术团队,在开发过程中全力相助,给予技术支持,帮助我们快速解决问题。