我使用UDP编写了多人Pong。我正在使用内插法和外推法,以便在客户端上产生平滑的效果。
有用。但是,球中经常会出现卡顿现象。每次接收到新数据包时,它都会向前跳跃一点。它看起来有些滞后,但可以播放。
必须有一种使游戏看起来更流畅的方法。我读过有关橡皮筋的信息。从这里搬家的最佳方法是什么?
希望有人能够很好地回答我的问题。
更新
根据Ivan的要求,以下是ping时间的图表。但是,我确实认为该问题存在于客户端平滑代码内。
最佳答案
通过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
假定正在交换两种包类型:
伪代码对update-entities线程中的所有未知数执行外推(“假设事情继续照常运行”)。出现问题的唯一点是用
<---
箭头标记。您可以通过将桨叶翘曲到新位置来轻松校正桨叶位置,并可能在短时间内插补运动以减少震动。
如果两个客户或多或少都同意,则校正球的位置很容易(然后您可以再次进行插值技巧,以进一步使之平滑)。但是,一个客户可能会看到差点错过,而另一位客户会遇到差劲。在这种情况下,由于您使用的是对等模型,因此我们让本地客户端进行调用,并说明对对手发生了什么(在另一种设计中,您将有一个中央服务器来做出此类决定;这样可以避免作弊。如果两个客户都不同意,您将无法避免在那里出现丑陋的跳动-但希望这应该是相对罕见且短暂的,除非它与ping尖峰同时发生。