我使用UDP编写了多人Pong。我正在使用内插法和外推法,以便在客户端上产生平滑的效果。

有用。但是,球中经常会出现卡顿现象。每次接收到新数据包时,它都会向前跳跃一点。它看起来有些滞后,但可以播放。

必须有一种使游戏看起来更流畅的方法。我读过有关橡皮筋的信息。从这里搬家的最佳方法是什么?

希望有人能够很好地回答我的问题。

更新

根据Ivan的要求,以下是ping时间的图表。但是,我确实认为该问题存在于客户端平滑代码内。

java -  "Rubber banding"会解决多人插值卡顿现象吗?-LMLPHP

最佳答案

通过previous question填充上下文,我了解到您正在从每个客户端向另一个客户端发送桨和球的位置。但是,只要客户就每个时间的桨叶位置达成一致,就完全确定了球的运动(排除了舍入误差),因此您应该尝试零结球。
每个客户都应保持自己的内部状态,即桨和球的位置和速度。伪代码将类似于以下内容:

// input thread
if input changed,
   alter paddle speed and/or direction
   send timestamped message to inform my opponent of paddle change

// incoming network thread
if paddle packet received
   alter opponent's paddle speed and/or direction at time it was sent
   fix any errors in previously extrapolated paddle position <--- Easy
if ball-packet received
   fix any errors in ball position and speed <--- Tricky

// update entities thread
for each entity (my paddle, opponent paddle, the ball)
   compute updated entity position, adjusted by time-since-last-update
   if ball reached my end, send ball-packet to other side
   draw updated entity

假定正在交换两种包类型:
  • 桨状包是带有时间戳的位置+桨状速度,每当客户端更改其自身桨状速度时都将发送该数据包。
  • 球包是带有时间戳记的位置+球的速度,无论何时球到达客户(本地)一侧,无论球是否从 Racket 上弹起,都将发送该数据包。

  • 伪代码对update-entities线程中的所有未知数执行外推(“假设事情继续照常运行”)。出现问题的唯一点是用<---箭头标记。

    您可以通过将桨叶翘曲到新位置来轻松校正桨叶位置,并可能在短时间内插补运动以减少震动。

    如果两个客户或多或少都同意,则校正球的位置很容易(然后您可以再次进行插值技巧,以进一步使之平滑)。但是,一个客户可能会看到差点错过,而另一位客户会遇到差劲。在这种情况下,由于您使用的是对等模型,因此我们让本地客户端进行调用,并说明对对手发生了什么(在另一种设计中,您将有一个中央服务器来做出此类决定;这样可以避免作弊。如果两个客户都不同意,您将无法避免在那里出现丑陋的跳动-但希望这应该是相对罕见且短暂的,除非它与ping尖峰同时发生。

    10-05 21:19