游戏开发论坛

 找回密码
 立即注册
搜索
查看: 32372|回复: 0

在luacluster中使用物理引擎

[复制链接]

58

主题

1437

帖子

2207

积分

金牌会员

Rank: 6Rank: 6

积分
2207
发表于 2022-5-10 09:49:13 | 显示全部楼层 |阅读模式
众所周知luacluster是第一个实现万人同屏的游戏服务器框架。然后就有无数人来问我为啥呀?思路呀?架构呀?雀实程序员现在都不看代码的呀!可我发了哪么多技术文章也都没人看!你敢信?哎~可是你们不看我也得发呀。真怕哪天我老死了,游戏服务器这门手艺怕是就失传了呀!哎,做技术不容易,关注得兄弟给点个赞吧!
[color=inherit !important]https://github.com/surparallel/luacluster​github.com/surparallel/luacluster
话说过来能不能在服务器使用物理引擎呢?使用物理引擎是没得问题的。把Bullet封装到DLL给LUA调用就可以。Bullet是多线程不安全的,所以在每个线程(luacluster中的docker)里创建一个物理引擎实体。在某个需要计算物理的场景时。可以把所有相关的物品放入物理引擎并计算想要的结果。在多线程或分布式状态下不能只创建一个物理引擎。因为很明显这个物理引擎会成为分布式下位置同步的瓶颈。但创建多个物理引擎就不能实时同步数据。因为也会导致性能瓶颈。这样物理引擎实际就变成每个服务器对象的一个计算工具。
在应用场景下。例如NPC发射了炮弹。哪么这个炮弹可以放到物理引擎里计算每帧的轨迹。然后在每帧把轨迹同步给AOI内的可见对象。如果炮弹在空中被拦截,对就是爱国者干的事情。哪么就要重新计算碰撞的轨迹。直到炮弹到达指定落点爆炸。
这里问题来了,如果每个物理引擎计算轨迹并在每帧同步位置。哪么相当于一个帧同步的消息广播源。这个帧同步的消息广播源。一直在服务器内引发消息动荡!!在《luacluster总体架构》中我说过要消灭纯粹的帧同步。因为任何帧同步的方式都非常低效。帧同步相当于玩家从A移动到B点。然后每帧都发起广播说A移动了0.1米。即使高频的枪战游戏。大部分时间里玩家的操作都是按秒计算的。慢于100毫秒的游戏高手更是屈指可数。同样在1秒钟从A移动到B。状态同步发送开始的位置和结束的位置以及移动的速度就可以了。帧同步尤其小于100毫秒的帧同步毫无意义。当然这里又会有人喷巴拉巴拉。因为所谓帧同步和状态同步都是在单位时间同步数据。这种划分本身就不严谨。例如,你妈妈给你打电话问你“小明,你爸爸在干什么。”。然后你说:"爸爸向前移动了0.1米,移动了0.1米,移动了0.1米,移动了0.1米,移动了0.1米,移动了0.1米..."。或者说:"爸爸在去开门!”。第一种回答肯定会被当成是傻儿子。第二种才是正常思维的人。
为了不被当成地主家的傻儿子。我们首先要对碰撞进行分类。看能不能解决我们的问题。哪么碰撞就会分为两种。固刷在地图上的物品碰撞和其他动态创建物品的碰撞。例如球碰到地面弹起再碰再弹起。就是动态创建的球和固刷物品的碰撞。这种碰撞是并不需要创建物理引擎的。使用多段贝塞尔曲线就可以完全模拟物品运动轨迹。我们可以根据受力的方向和物品的质量调整贝塞尔曲线的参数。也就是大部分的碰撞问题都可以用多段贝塞尔曲线来模拟。我们知道贝塞尔曲线就是一个多段的坐标数组。
贝塞尔曲线
这样我们就可以把这数组发送给所有客户端。在客户端创建并模拟球在地面弹跳。这样既不用物理引擎也不用帧广播同步。服务器效率提升爽到爆炸呀!
还有一种情况就有点头痛了。就是创建的物品之间产生碰撞。例如绝地求生中打空中的燃烧瓶。在服务器拿到燃烧瓶的贝塞尔曲线和子弹的贝塞尔曲线。然后计算两个曲线的最小间距是否小于燃烧瓶。如果小于就判断碰撞,然后返回客户端燃烧瓶爆炸。我们的所有问题完美解决。不用在服务器塞入又大又臃肿的物理引擎了。
然后我发现给自己挖了一个大坑。这样就需要在luacluster上实现下面两个功能。
1,需要一个算法把物理量转化为贝塞尔曲线。
2,需要一个算法计算两个贝塞尔曲线的最小距离。
我找到了一个贝塞尔曲线库(TinySpline)。但物理量转成贝塞尔曲线的算法没找到。所以你们问我luacluster为什么能实现万人同屏。这就是你们要的万人同屏技术呀!每天都在解决这些乱七八糟的算法问题。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2024-3-29 01:50

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表