同步算法-客户端障眼法

就像魔术虽然是假的,却能给观众带来欢乐一样,尽管网络延迟不可避免,但是在客户端实施点障眼法,玩家就能收获良好的游戏体验。

一、插值算法

客户端收到移动协议后,不会直接设置角色坐标,而是让角色慢慢往目标点移动。如图所示,服务端在0秒、0.2秒、0.4秒时分别发送了3条移动协议,告知角色在A、B、C三个点。

当客户端收到B点协议时,不直接设置位置,而是让角色慢慢走向B点;收到C点协议时,再慢慢走向C点。使用插值算法,就算是以0.2秒一次的低频率同步,玩家也能有较好的游戏体验。

作为障眼法的代价,插值算法比“直接设置位置”存在更大的误差。在图8-11所示的场景中,客户端第0.4秒才走到B点,0.6秒才走到C点,增加了0.2秒的延迟。

但无论如何,比起“直接设置位置”那种玩家体验极差的游戏0.2秒的延迟是值得付出的。

 

二、缓存队列

单纯的插值算法还不能解决顿挫问题。回顾下图,其中第3条到第7条协议几乎同时到达,

下图展示了仅仅使用插值算法来做优化的情形,顿挫问题依然存在。

假设插值算法增加了0.2秒的延迟,即收到移动协议后,让角色花0.2秒的时间从当前位置移动到新位置。

那么角色从A点走到B点(很短的距离)花费的时间为0.2秒,从B点走到C点(较长的距离)花费的时间也是0.2秒,移动速度发生突变,故而会影响玩家体验。

客户端可以通过缓存队列来缓解速度跳变的问题。

如下图所示,收到移动协议后,不立即进行处理,而是把协议数据存在队列中,再用固定的频率(比如,每隔0.2秒)取出,结合插值算法移动角色。

“缓存队列”相当于是在客户端加一层缓存来缓解网络抖动的问题,这样做能够有效提高玩家的游戏体验。

客户端还可以动态调整取出的速率,当队列里积累了较多数据时,可以稍微加快,当队列中的数据很少时可以稍微减缓,从而可以更好地抵抗网络抖动。

但比起单纯使用插值算法,缓存队列付出的代价是误差更大。

结合插值算法和缓存队列,单靠客户端的优化就能够解决大部分同步问题。对于误差敏感的游戏类型(如射击),还可以通过“主动方优先”的策略来提高玩家的游戏体验。

三、主动方优先

插值算法、缓存队列会加大不同玩家所见画面的差异。客户端画面差异越大,“打不中”莫名其妙被打死的问题就越有可能发生。

对于这种问题,一般会采取三种应对策略,具体如图所示:

  • 第1种:不管客户端的误差,一切以服务端的计算为准。例如《球球大作战》,不论玩家看到怎样的画面,小球吃到哪个食物、碰到哪个敌人都由服务端裁决。这是一种最权威也是最难实现的方案,因为该方案要求服务端具备完全的运算能力。
  • 第2种:信任主动方。客户端A发送“我击中了B”的协议,只要不是偏差太大(例如,角色A和B隔得太远),服务端就认定A真的击中了B。这种方式会提高玩家A的游戏体验,但玩家B可能会感到“莫名其妙被打死”。
  • 第3种:信任被动方。客户端B发送“我被A击中”的协议。这种方式会提高玩家B的游戏体验,但玩家A可能会感到“明明瞄准了却打不中”。

有时因为项目期限和开发难度的限制,很多游戏的服务端并不具备完全的运算能力。《球球大作战》的位置、碰撞能由服务端进行运算,是因为游戏很简单,计算量不大,但如果游戏很复杂,那么开发难度就会很大。

有些项目会让客户端发送位置坐标,服务端只做转发,这样能减少很多工作量。如果服务端不具备运算能力,那么我们通常会选择第2种方案。这是因为“主动方"玩家更具活力,更有价值,要优先照顾他们的感受。

"被动方”说不定正处于挂机状态,可能并不在游戏屏幕前。总而言之,虽然误差不可避免,但可以通过“主动方优先”的策略来进行应对,提高重要玩家的游戏体验。

posted @ 2024-06-20 18:37  独一无二~  阅读(74)  评论(0)    收藏  举报