Bmob后端云-让移动开发更简单Android开发经验谈Android开发

如何实现各种游戏的思路杂想

2018-03-23  本文已影响95人  大王12

据Bmob官方人员的透露,他们一开始产生做Game SDK的念头,主要就是因为吃鸡的火爆。

(还有一大原因是,从后台数据、客服与开发者一对一聊天获取的信息来看,使用Bmob目前服务的开发者中,需要游戏实时数据云服务的开发者占了很大的比例。)

1.jpeg

所以一开始Bmob团队开发Game SDK和Demo的时候,都是复刻 蓝洞的绝地求生 这款游戏,努力在还原所有这个正版游戏的设定。后来历经沧桑,开发到游戏 能跑了微信小游戏 又出来了,而小游戏需要实时传输数据 仅支持Web socket ,且很多人都看好在这个小游戏平台开发的休闲类、益智类、棋牌类等等轻量的游戏。这样一来,以前面基于 FPS 开发的、 强交互 的、高频处理数据 的云服务就不适用了。

2.jpg

于是Bmob团队把这一套服务 几乎完全推倒重来,把核心算法保留下来后,再借鉴众多游戏的思路(其实就是主程沉迷过的游戏),解剖各类型游戏的各种场景,重新开发了一套BGS系统(心疼前面那一套花掉的血与泪一秒钟)。以下以 《梦幻西游》《绝地求生》 游戏为小节,分析一下如何用BGS实现。

(笔者只是Unity开发萌新一枚,非专业游戏行业人士,如有错误,还望谅解)


梦幻西游

3.jpg

这个游戏真是让人又爱又恨啊,想当年...

好吧我们还是从技术层面来讨论一下。

也就是说,在你网络不好的情况下,连物品栏你都调整不了摆放的次序,选中的东西会没掉,且不会移动到你指定的地方
如果你要说,这不是废话吗?哪个游戏不是非常依赖数据库?那你就错了,很多实时对战的游戏还真不需要,例如FPS,只要在战斗开始时获取一下玩家姓名和皮肤,战斗结束时记录一下战绩就可以了
也就是说,在你网络不好的情况下,连走路你都走不了,就算在客户端来看你迈出了几步,但是网络一恢复,你原来在哪还是在哪
如果你要说,这不是废话吗?哪个游戏不是全通过服务器来计算?那你就错了,很多实时对战的游戏还真不需要,例如FPS,玩家的位置在哪里、是否击中目标对其它玩家造成伤害,都是客户端自己说了算的,因为很多服务器没有内置整套的物理引擎,即使有,造成的服务器消耗太大,成本也太高(试想一下,在PUBG巅峰300w玩家同时在线的时候,可能有6w个房间,每个房间都要有一套物理引擎,一局据说有10万+颗子弹,每一颗子弹飞出去都需要有弹道下坠,要逐帧计算初速度和重力加速度,以及和整个地图海量的3D刚体进行碰撞检测)。这也是为什么PUBG有飞毛腿、隔山打牛、瞬移、神罗天征、万象天引等等外挂了
也就是说,在你网络不好的情况下,哪怕你身边人山人海,你也可能一个人都看不到,而你在荒无人烟的野外跑商的时候,连聊天都比较流畅
如果你要说,这不是废话吗?哪个游戏不是只传递可视范围内其它玩家的信息?那你就错了,很多实时对战的游戏还真不可以,例如FPS,你朝远方、朝天边随便开一枪,也可能射死个几千米以外、无需渲染的玩家,这也是为什么透视外挂再远能够看到所有玩家的信息
4.jpg

那么,如何使用 Bmob Game SDK 来实现像 梦幻西游 这样的一款网游呢?

绝地求生大逃杀

5.jpg

欢迎四排组队,本人亚服排名3w求大腿...

好吧我们还是从技术层面来讨论一下。

我觉得比较有意思的讨论点在于:

HP的控制

FPS类,或者说所有有PVP模式的游戏,都有一个共同的烦恼,就是Damage谁来判定的问题;选项无外乎三个:攻击者被攻击者服务器

所谓高Ping大神,就是将自己的网络搞差,例如利用南辕北辙的加速器,或者本身就是"卡B",他们可以在敌人的千军万马中几进几出,毫发无伤;说极端一点,拔掉网线,就可以进入无敌状态,还附送大招CD恢复
锁血挂的实现原理有很多种,有一种就是篡改本地逻辑或拦截网包,以破坏上报自己受伤的信息,服务器永远不知道客户端受到了伤害,在其它玩家看来就相当于锁血了。
所谓隔山打牛,其实就是利用了子弹与其它玩家的碰撞检测时发送信息给服务器这一点,如果hook了这个函数,或者破解了这个信息的网包协议,随便开一枪都可以将子弹精准得"碰撞"到对方头上,因为服务器傻啊
虽然上面已经讲过了,但这里为了字数再啰嗦一遍:
PUBG的玩家同时在线巅峰值是300万
假如每个房间有50个人(不要说100人,有很多房间在决赛圈呢)
就会有有6万个房间正在进行游戏
每个房间都要有一套物理引擎
每一颗子弹飞出去都需要有弹道下坠,这意味着要逐帧计算初速度和重力加速度,来确定子弹位置
子弹飞出去后,要逐帧和整个地图海量的3D刚体进行碰撞检测
Uzi射速是0.048s/发
据分析源码的人说一局据说有10万+颗子弹
服务器判断可信度的方式有很多,等级也分很多种:
1. 最低级的判断,通过一些常识来实现逻辑,例如一发喷子不可能打在位置相差甚远的不同的7名玩家身上
2. 中层次的判断,丢一个二向箔,把整个坐标系拍成2D(无视y轴也就是海拔高度),在攻击的瞬间,攻击者的朝向要和被攻击者一致(角度在一定误差范围内),这个可以通过简单的三角函数计算得到
3. 略高层次的判断,服务器要包含一套地图的3D低模,当某玩家声称击中另一个玩家时,可以模拟一下激光枪是否会接触到低模(障碍物),可能会出现低频的误判

以目前的BGS内测的情况来看,做到 攻击者 结合 服务器 判定,并且加上 中层次的判断 是完全没问题的:

要求开发者写云端代码,在云端代码添加 PositionRotationBmobGameHook ,在上报玩家击中事件时,用 java.lang.Math 里面的三角函数就可以简单判断一下这次击杀是否合理了

6.png

安全区机制

安全区肯定是服务器统一确定的,并且是逐帧计算的

7.jpeg
  1. 大圈半径减去小圈半径得到一个数字,以这个数字为半径弄一个圆
  2. 随机一个圆内的点,再加上大圈的圆心坐标点,作为下个毒圈的圆心
  1. 半径按每帧m米的速度减小
其中m = (大圈半径 - 小圈半径) / 帧数
  1. 圆心按每帧n米的速度从大圈圆心移动到小圈圆心
其中n = [(大圈圆心x - 小圈圆心x) / 帧数, (大圈圆心y - 小圈圆心y) / 帧数]

这一套完全可以用Bmob Game SDK的云端代码的 Room.onTick 实现,然后再逐帧向客户端下发当前的安全区的圆心和半径,并且结合 Player.getPosition ,计算玩家是否在圈内,如果在圈外的,调用 Player.setHp 进行减血

请注意,上面提到的 getPosition、getRotation、onAction_Damage、setHp (还有类似 onUpdate_Posision)等方法,都不是Bmob Game SDK云端代码自带的!而是开发者在设定了他游戏有hp这个属性后,在上传的 Player.java 类内,直接按这种命名规则写这个方法就可以读取、监听、修改这些属性啦,超方便的!

有什么好的建议,给我留言,或者直接去Bmob游戏开发官方群中呼唤我:
Q群:726133616

其他教程

落地成盒?Bmob帮你开发自己的联网"吃鸡"游戏

Unity联网对战游戏小Demo

上一篇 下一篇

猜你喜欢

热点阅读