如果有计算,那结果是是肯定不会完全一致的。
但是我的做法是,谁的属性的负责,比如说你发射的子弹,在我的客户端中,只是图片,不参与碰撞和计算,或者只碰撞不计算伤害,由你的客户端计算好然后广播结果给我。这样就能保持结果一致。PS:不考虑作弊
这样做有问题啊,B玩家的子弹不在A玩家做碰撞和逻辑运算,就会发生B玩家的子弹在A玩家客户端对A玩家穿身而过,过了1秒后(网络波动,接收数据时间不定),B玩家把伤害发过来,这时A才被计算伤害。
mark等于学会
我有个疑问,后台是怎么实现固定时间同步数据给客户端的。我想的是用定时器,但是定时器,就会有帧率问题,不一定每帧的间隔都一样吧?
说简单点,这就跟军训时,喊的121一样,喊一步走一步。教官不喊下一步,脚就得一直抬着
就是假装它是一样的就行了
好的,我再继续啃一下大佬的demo代码。我之前做是各自客户端模拟服务器以固定帧做逻辑推算,会出现有点帧长有的帧短,然后做碰撞检测就会不一致了。想来当时也没有做帧号之类的记录和处理。
哪来的浮点数!乘以一万不香么?
实操起来太麻烦了
你同步游戏的碰撞检测是用什么做啊?怎么会不一致呢?
还有后端发给前端的固定帧率用定时器就可以了,因为后端不用做渲染,每一帧间隔的时间有差异也不影响前端,前端做平滑过渡就可以了。就算你做到后端的发送帧率间隔时间没差异,但是经过网络传输,网络波动这些问题,前端收到的服务端帧率间隔时间也是很大差异的,比如上一帧的时间间隔是0.1s下一帧有可能是1s,所以你花心思怎么把后端发送帧率固定是没用的。
你想用定点数可以用BigNumber插件,这个可以做定点数运算。
是的,我也发现这个问题了。我当时的做法是没有帧号这个概念的,服务器也只是做了转发,没有固定频率给客户端发送消息。碰撞检测用的是碰撞盒做的,因为执行的时间不一样,两个碰撞盒的位置不一样,所以在检测的时候就会不一致了。归根结底还是实现方式出了问题。
BigNumber运行效率太低了
你用引擎自带的碰撞盒或物理碰撞是做不了帧同步的。
因为碰撞盒和物理引擎的检测是基于引擎的渲染帧处理的,也就是脚本里的update,因为每个客户端的update的帧率都不一样,而且每时都在波动,怎么可能会在同一时机都检测到碰撞呢。
举个最明显的例子,A客户端的渲染帧率是60帧/s,B客户端机子性能比较差,只有30帧/s。也就是说A客户端每秒做了60次物理检测,B客户端每秒只有30次,大家检测碰撞的次数都不一样了,还怎么同步呢,如果B客户端的机子再差些,只有10帧/每秒,一颗子弹快速飞向玩家,很可能会穿墙而过,而在A客户端就能命中。
再举一个例子,如果一个玩家在玩的过程种,暂时把游戏退出后台几秒钟,这时渲染帧update停住了,物理引擎也停止了,但是另一个玩家的游戏还在跑,物理引擎还在正常检测,结果一段时间后,这个玩家把游戏从后台打开,物理引擎接着上一次停止的位置继续跑,而另一个玩家可能游戏早就结束了。
帧同步要做得到碰撞检测也相同,只能自己在逻辑帧里自己写碰撞算法,如果两个玩家都用圆形碰撞表示,就算两个玩家的距离是否小于两个玩家的半径之和就知道是否碰撞了,比如大家都在逻辑帧第10帧做这个算法检测碰撞,那么大家就能做得到在同一时机检测到碰撞。当前如果要用其它不规则的碰撞可以自己实现。
可笑的是现在很多人做帧同步碰撞检测还在用引擎的物理系统和碰撞系统做检测的,包括很多做网课的老师都这么玩,遇到不同步问题的时候到各技术论坛里喊救命。
你既然选择了定点数运算,就要接受运算效率低的问题。定点运算怎么玩也不可能玩出浮点运算的效率的
额,我这里是用的自己的碰撞检测,不是引擎的。每个物体都有自己的一个碰撞框,也是在自己的逻辑帧里处理的(其实这里的逻辑帧跟渲染帧是一样的,客户端的逻辑帧也是靠引擎的帧来刷新)。
看了半天,楼主这是自己搭建服务器,是吧?成本的确能省,电费、宽带本来每家就是要用的,淘汰的二手机器整一个做服务器,日活几百的小游戏足够了吧。
帧数据战斗中上报服务端,服务端拿客户端的逻辑帧代码去跑,战斗结束客户端关键数据MD5后发给服务端,服务端比较自己跑的结果。
验证服务和同步服务需要拆分,不要丢一块,验证很耗CPU。
楼主在误人子弟,参照这个大佬的回答,指出几个错误点:
1:“几像素误差不重要”,相反,帧同步不能有误差,否则还叫啥同步?几像素误差就可能导致子弹偏差,最终带来战斗结果误差,要么拿坛子里其它大佬写的计算库,要么就是Math.floor(value/1000)*1000,要么就别用浮点数
2:楼主的做法跟我回复的这个大佬不一样,真正意义的帧同步就是同步操作,因为需要低时延,所以同步的数据越少越好,楼主的这个同步严格来说叫做:“状态同步”,相比较状态同步,他服务器不跑逻辑,他口口声声说省服务器钱,而他这做法带来的结果就是数据流量非常大
3:跳帧,帧同步的是客户端的操作在本帧是不进行动画播放的,需要等待服务端返回本帧的操作再进行位移等动画,如果延迟高,就会丢弃掉这个操作的响应,这不叫跳帧,他说的王者荣耀继续向前走那叫做“预测”,等下一帧数据到来的时候,这个“预测”进行丢弃,重新从预测前的那一帧开始跑
4:引擎的碰撞检测是不能用的,逻辑帧的代码一般都是前后端通用,你上了一般的物理引擎,服务器咋做验证?这是一点,第二点,浮点型问题,我回复的这哥们已经说了,不做解释。我现在的做法是,不用box2d等物理引擎,不过PolygonCollider2D组件是用的,给策划用,目的让策划去布置多边形,程序取多边形,然后自己写碰撞检测,算法不难,判断一个点是否在多边形内、判断多边形是否相交,另外的四叉树优化啥的算法不多做叙述
楼主本心共享技术是好的,赞成,不过不对的地方最好虚心接受,我回复的这个哥们一看就是做过的,向他学习没错
给你点个赞。3叫帧同步的预测回滚,是帧同步里比较难的地方