在多人游戏中插值位置


14

为了节省多人游戏的带宽,我不会在每个服务器滴答声中更新每个对象,而是每个对象都有一个updateRate来告诉游戏该对象应在每个X服务器滴答声中进行更新。

当我收到某个对象的更新消息时,我会计算出我希望下次更新的时间:

origin = serverCurrentPosition
diff = serverNextPosition - origin
arriveTime = now + timeBetweenTicks * updateRate

当我绘制对象时,我计算了到下一次更新为止的剩余时间,并据此插值位置:

step = 100 / timeBetweenTicks * updateRate
delta = 1 - step * ((arriveTime - now) / 100)
position = origin + diff * delta

它可以工作...但是在图形中仍然有些抖动,尽管按照我的理论,每件事都可以解决,因为缩放应该照顾一些滞后,应该吗?

所以这里的问题是,这是最好的方法吗?我应该在计算中加入实际滞后吗?如果是这样,我该怎么做?我做了一些实验,但抖动只会变得更糟。


嗨,伊沃。我认为这是一个很好的主题,但尚不清楚您的代码在做什么-例如,serverCurrentPosition,serverNextPosition,timeBetweenTicks来自何处?
CiscoIPPhone 2010年

这将发送来自服务器的更新数据。
Ivo Wetzel

Answers:


11

您有抖动,因为您的延迟在不断变化。这意味着,尽管服务器在每个timeBetweenTicks滴答中都发送更新,但客户端在某个可变时间后会收到更新。该时间可能接近timeBetweenTicks良好的连接时间,但并不完全相等(此外,服务器滞后,服务器和客户端的时钟速度不同)。

因此,当您依赖于恰好在指定的时间内接收更新时,您会在实际更新之前/之后不断到达目的地。因此,抖动。

减少抖动的简单方法是使用“橡皮筋”,这是马丁在另一个答案中建议的。基本上,当您收到更新时,您不会立即更改对象的位置。相反,如果客户端位置和服务器位置仅稍有不同,则开始插值客户端位置,以便在指定的时间(例如,下一次更新的一半)之后,客户端和服务器位置会收敛。

减少设置中抖动的另一个想法:由于您同时传输“当前”和“下一个”坐标,因此可以计算对象的速度。然后,当更新滞后时,您无需将对象停在其目的地(即“下一个”位置),而是继续以相同的速度移动它。如果您的对象没有突然改变其速度,这将真正提高客户端的运动平滑度。


已经如此,这些对象不会停止,它们会继续前进直到收到下一个更新。另外,在HTML画布上使用硬件加速似乎可以大大降低抖动效果。从事了这么长时间的工作,也许我只是疯了。
Ivo Wetzel

那很有可能。如果打开加速使帧速率更高,则在恰好合适的时机处理更新信息的可能性会增加。
没关系,2010年

9

我已经成功解决了这个问题,并通过一种称为“网络阴影”的方法取得了一些成功。我不知道这是别人做的事,但对我来说总是有用的。

跨网络同步的每个实体都有一个不可见的网络影子实体。当网络中有更新更新时,您可以将阴影直接传送到网络说应该位于的位置,然后随着时间的流逝,向阴影逐渐内插本地可见实体。

包括我对这种做法在我以前的答案很多细节在这里


嗯,我在较早的版本中做了类似的事情,浮点数的不精确有时使它变得非常糟糕,更新之间我有相当长的时间跨度,某些对象的时间跨度最大为300ms,但也许我只是做错了,我会给它当我找到一些空闲时间时拍一下照片:)
Ivo Wetzel

浮点精度真的不应该包含在内!您是否阅读了我关于stackoverflow的链接答案?它涵盖了实现这种事情的所有细节。
马丁

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.