程序员人生 网站导航

快速多人游戏(3) - Entity插值

栏目:框架设计时间:2016-06-16 08:38:48

原文链接:Fast-Paced Multiplayer (Part III): Entity Interpolation

介绍

在系列的第1篇文章中,我们介绍了1种权威服务器的思想还有他在避免玩家做弊方面的优势。但是直接使用这类技术会引发可玩性和响应性方面的问题。在第2篇文章中,我们提出了1种客户端预测的方法来处理。


到现在为止我们提出了1套解决方案,能够让玩家在多人游戏中得到单人游戏般流畅的体验,即便是在接入权威服务器并且有1定网络延迟的情况下。


在这篇文章中,我们将会处应当有别的玩家连入相同的服务器的问题。


服务器时间步长

在前面的文章中,服务器的行动非常的简单 - 读取客户真个输入,更新游戏状态,然后将结果返回给客户端。当超过1个客户端连接的时候,服务器的主循环逻辑就有点不1样了。

在这类情况下,1些客户端可能同时快速地发送输入(比如按方向键,移动鼠标或单击),每次收到客户真个要求就更新游戏,然后再把救过进行广播, 这样会消耗大量的CPU和带宽。


1种好的方式是将玩家的输入压到队列中去而不马上进行处理,服务器在1定的频率上进行相对低频率的更新,比方说没秒10次。每次更新之间的时长称为时间步长,在这里是100ms。在每次的更新迭代中,所有的未处理的输入都今次那个处理(可能会比时间步长更小1些,来让物理更可预测1些)然后新的游戏状态就广播给所有的客户端。


总的来讲,游戏世界的更新应当在1种可预测的频率,独立于玩家的输入。


处理低频率的更新

从玩家的角度看,这类方式还是像之前的方法1样顺滑 - 客户真个预测独立于更新的延迟,所以对可预测的状态更新是没有问题的。但是,由于游戏状态以1种低频率进行广播,这将致使游戏看上去非常卡顿,多是100ms更新1次位置。




在客户端2中看到的客户端1的情况


根据你开发的游戏类型,可能有很多方法来处理,通常你的游戏实体越可预测,越好处理。


航位推

假定你在做1个赛车游戏。1辆快速开着的车是非常可预测的 - 假定他的速度是100m/s,那末1s以后,它应当大致在离起始点100m远的位置。


为何是“大致”?由于在这1秒中以内,车可能加速1点,也可能减速1点,向右1点或向右1点 - 这里说的是1点点。由于车的机动性,车确当前位置总是依赖于它之前的位置,速度和时间。而不是玩家的输入,换句话说,1辆快速运行的车没法瞬间180度掉头。


1个每秒更新10次的服务怎样来处理呢?客户端收到每辆车的速度和朝向以后,在接下来的100ms内,它不会遭到任何新的信息,但是客户端还是要进行更新啊。最简单的方法就是假定车在这100ms内,朝向和加速度都是常量,然后让这辆车继续运行,100ms以后,收到更新包以后,再对车的速度进行纠正。

纠正可能很大也可能很小,依赖于很多因素,如果玩家保持直线运行并且不改变车的速度,那末预测的结果和正式的位置是完全1致的。另外一方面,如果玩家撞到甚么东西,预测的位置就完全错了。

有1点要提1下,航位推的算法可以利用在慢速的情况下 - 比如战舰。其实这类算法最初就用在海上导航。


Entity插值

有许多情况航位推是没法处理的 - 对玩家的方向和速度可以瞬间改变的都不行,比如3D射击,玩家常常快速跑动,停下,快速转向等,在这类情况下,航位推算法就非常无力了。由于位置和速度和前面的数据无关。


你可以选择在接到服务器的要求的时候直接更新玩家的位置,而客户端看到的就是网上其他的玩家每100ms跳1下,感觉会非常奇怪。


你现在具有的是每100ms由服务器传送过来的权威数据,现在要做的是如何在这100ms内让网络角色看起来非常自然,解决问题的关键就是将网络玩家显示在过去的某个时刻。


假定你在t=1000收到位置信息,你已在t=900收到了1次位置信息,所以你知道玩家在t=900和t=1000的位置,所以在t=1000到t=1100之间,你只要显示玩家t=900到t=1000的位置。这类方法,你所显示的都是玩家的真实数据,只是有100ms的延迟。




客户端2渲染的是客户端1的角色过去的位置,利用插值来更新位置


用来插值的t=900和t=1000的数据依赖于游戏。插值通常都可以处理得很好。如果不是这类方法,你可能需要服务器发送更加详细的移动信息了 - 比如更多的位置采样点,或每10ms发送1次(你没必要发10倍的数据 - 由于你发的微小的位移数据,在这类情况下数据的格式可以很好的优化1下)。


当使用这类技术的时候,每个玩家都和游戏世界有1点点不同步,由于每一个玩家看到自己的世界是当前的,但是其他的玩家都是过去的。但即便是快速的游戏,这100ms的延迟都不是那末明显。


有1种情况除外 - 当你需要时间和空间的准确性的时候,比如1个玩家射击另外一个玩家的时候,由于其他的玩家都是存在于过去的某个时候,你的瞄准实际上是有100ms的延迟的 - 也就是说,你设计的目标是100ms的某个目标! 这个问题我们下1篇会进行讨论。


总结

在权威服务器的环境中,有着不肯定的服务器更新和网络延迟,在这类情况下你还要给玩家平滑的移动。在第2篇中,我们展现了1种客户端预测和服务器调和的技术,来实现实时的角色控制,这样的方案让玩家能够得到即时的反馈,移除致命的延迟。

其他玩家的同步还是1个问题,但是,在这篇文章中,我们提出了两种解决方案。

第1种是航位推技术,这类摹拟需要entity的位置能够通过前1个时候的位置,速度,加速度来推算出来,当不满足这类情况的时候,航位推就没用了。

第2种是插值技术,不预测将来的位置,只是使用服务器传来的数据,这类就会造成显示的entity总是过去的某个时刻。最后的结果就是玩家的角色总是当前时刻,而其他看到的entity都是过去的某个时刻,这类情况可以产生1种难以置信的无缝体验。

但是,当游戏需要高速离散的准确性的时候,比如射击或移动物体,美景就幻灭了:你看其他玩家的位置和服务器的位置不1致,别的玩家看你的位置也不是正确的,这样爆头就不可能产生了!很多游戏都有爆头这1说,我们将在下面的文章中来讨论这个问题。





------分隔线----------------------------
------分隔线----------------------------

最新技术推荐