《野蛮人大作战》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

转表工具,原来转表工具不支持 json 格式,找到公司公共部门帮实现了支持 json 格式的转表工具。

工具齐全,搞起搞起,加班加点一个月左右的时间完成了单局部分,就是可以看到角色 AI,可以在场景中互相砍杀,在这过程中遇到最多的问题,就是 js 的引用问题。比如:

var obj = {x:0,y:0};
var obj2 = obj;
本意是想复制一个对象,但是 js 中对象赋值都是引用,只要操作 obj2 就会导致 obj 对象中的数据变化,这和 C++ 不太一样(我们多是从 C++ 转过来),当逻辑复杂的时候不是很好找。

网络版本。网络部分采用 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.网络部分
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 官方技术团队,在开发过程中全力相助,给予技术支持,帮助我们快速解决问题。

长按识别二维码即可体验

34赞

顶一下

:clap:

楼主一上线就被腾讯代理了还是?

66666666:+1:

mark

感觉没有太多含量啊 楼主在开发中是什么角色

@77501578 Box2D不是一个确定性的物理引擎啊,楼主怎么修改成支持帧同步的引擎呢?我看文章里只有一个三角函数查表,其他碰撞之类的是怎么解决的呢?

肯定是主程吧。

赞一下

厉害了 赞一个

赞~ 对我很有帮助, 谢谢

谢谢分享!游戏不错,文章写得也很好,可以请教几个问题吗?
1、“网络收数据的时候指令顺序问题,导致不同步”,这个是这么解决的?
2、UI的刷新率如何单独控制呢?
3、box2d 有哪些改动呢?可否共享

1赞

关于帧同步的问题,ccc 没有提供物理引擎的step方法,没办法帧锁定的时候只锁定物理引擎。我用的是cc.game.pause() 然后加了一个interval 进行cc.game.step()追帧计算。这样所有的Component的update方法依旧可以用,但是如果出现网络延时连同UI一起卡住了,cc.game.pause()把所有的内容都暂停了。有什么更好的方法在ccc中实现帧锁定吗?

昨天试了一下小米5还是很卡呀,虽然确实比几个月之前流畅一些吧,但依然没法儿玩呀。
可以简单说一下浮点数咋处理的吗?
以及表现层的平滑处理么?

UI 可以通过工具转换成 Cocos Creator 所支持的格式 (这个是用什么工具呢 ?)
2d-x 格式的动画转换成 Creator 所支持的格式(从git上下载下来了。这个怎么使用呢 ?)
麻烦会的大佬 回复一下 谢谢

mark

强烈请求楼主回复一下这三个问题,论坛有你更精彩。
1、“网络收数据的时候指令顺序问题,导致不同步”,这个是这么解决的?
2、UI的刷新率如何单独控制呢?
3、box2d 有哪些改动呢?可否共享

1。每个包带ID,2、3同等楼主回答