战斗同步策略之状态同步

  最近实现了个多人战斗的小demo,采用的是状态同步策略。所有的逻辑运算全部在服务端进行,服务器以0.1s的固定时间向所有客户端推送帧消息队列,客户端的逻辑运算全部由服务器的关键帧来驱动。
  在这种同步策略下,所有客户端上看到的敌方单位运动情况都会是绝对一致的,因为客户端的这些数据全部来自于服务器。但是由于服务端的关键帧数只有1/0.1 = 10,如果按照这个帧数来渲染画面,游戏表现的就会相当卡顿,体验很不好。所以,对于客户端就需要解决同步策略下的画面渲染问题。这里采用渲染帧和逻辑帧分离的策略。在客户端维持一个消息帧队列,每次接受到服务器推送过来的消息时便会把收到的消息帧插入队列中。然后在逻辑帧中处理这些消息帧队列中的所有帧数据,在逻辑帧中计算好所有单位的终点坐标、旋转角度等信息。然后在渲染帧中对这些数据进行插值渲染,每次逻辑帧中运算出来的结果,需要在渲染帧中花费time的时间去完成渲染。time取值至少为0.1,这个取值需要根据服务器推送的关键帧的帧率来进行相应的修改,以此保证画面的流畅。
  采用状态同步可以很好的规避客户端作弊的问题,但是服务端便需要实现很多模拟客户端的运算逻辑,比如比较麻烦的就是物体间的碰撞检测。这个小demo采用的是两个多边形的碰撞检测算法——分离轴。可以参考这篇博客。博客地址
  
  状态同步,客户端在做优化处理时,需要注意下面几个点:

  1. 尽可能避免使用刚体,所有的物体运动均采用公式进行运算,因为刚体会受物理世界的模拟影响,但是客户端又受制于服务器发送的位置等信息,这样子刚体会在运动过程中产生一些不可控的路径
  2. 需要及时清空已经读取了的帧数据,避免帧队列过长导致逻辑操作过慢,但要避免在遍历帧队列的时候进行清空操作,防止遍历删除时产生异常报错
  3. 消息均由事件驱动,只有我方单位发生了明显的操作时才向服务器发送消息请求。但如果加入了刚体或者引擎自带的碰撞机制,则还需要一个固定时长的强制状态同步机制,以此来保证各个客户端的完全一致性

      这里写图片描述

发布了47 篇原创文章 · 获赞 8 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/it_wjw/article/details/76578165
今日推荐