多人手机游戏的网络延迟

时间:2012-03-05 08:41:40

标签: networking mobile physics corona multiplayer

我们正在使用Corona SDK及其物理引擎沿着某种类型的景观移动物体(如Tiny Wings),我们有一个关于位置校正的问题。假设一个盒子沿着起伏的山丘行进,但它的位置是在另一个设备上计算的。每秒几次,你收到:

  • 更新的职位
  • 盒子的速度
  • 发送信息的时间

所以我们知道这些信息是X毫秒,并且想知道它现在应该在哪里(假设它受到物理影响)并继续模拟直到我们得到另一个更新。 现在,我们尝试简单地将速度乘以自包裹发送以来的时间量,但正如您可以想象的那样,如果地形是弯曲的/不平坦的,那么这种行为确实很差。

有没有办法说:“停止一切并给我这个盒子的位置,如果物理对X毫秒采取行动,然后恢复游戏玩法”而没有实际停止X ms的所有游戏玩法?

2 个答案:

答案 0 :(得分:0)

我不知道Corona SDK,但是你可以做到这一点的一种方法是在每个游戏循环中模拟你的物理世界。当你收到真正的位置时,你可以更新你的物理世界。

某些物理引擎可能无法正确模拟较长的持续时间,因此建议执行比一个大步骤更多的小步骤。因此,在您的情况下,每次迭代都要做X ms,但步数较小,这样您就可以获得非常准确的模拟。

此处还有一件事是,当您收到实际更新时,框移动似乎会跳跃,因此您可能需要在几个游戏循环中将其平滑。

答案 1 :(得分:0)

20个月前你问了这个问题,你可能已经解决了这个问题,但我会尝试为将来的访问者回答这个问题:

没有一种最佳方法可以解决这个问题,总有正确性 - 延迟权衡,但以下是对它的一些想法。

原则上,网络物理和网络游戏逻辑没有区别,它是网络同步。我们可以尝试将其抽象为意味着有一些事件(空间+时间+状态),所有同行都应该同意。该事件可能是由物理引擎或其他任何东西计算的特定对象状态。

您描述了您的数据包在事件发起时包含特定的位置和速度(状态)和时间戳。每个对等体告诉其他对等体(直接或通过服务器)其当前状态是什么。

有一种方法可以更好地进行同步(在我看来):对等体不应该知道它的当前状态是什么,而是告诉它希望对象在将来具有X毫秒的状态

引擎应尽量使X尽可能接近以下总和:

  • 客户端之间观察到的延迟
  • 稍微插值时间
  • 一点安全边际

注意:通过不断发送消息和分析响应时间,它可以找到观察到的延迟

如果延迟突然恶化且安全边际不足,那么游戏将会短暂放缓,直到X被调整为止。

模拟转弯是交错的,每个事件事先得到宣布,以便每个客户都可以接收它,将其添加到时间轴然后插入并解析它到时候。

第X毫秒落入的模拟转向可称为目标转弯。

(未来的读者:请注意,模拟转弯通常与FPS不同,通常它们的频率要低得多,例如每10帧或每100毫秒或,我喜欢这个最好的网络可以提供)

示例:

[Turn0] a client/physicsengine announces event e1
[Turn1] a client/physicsengine announces event e2
[Turn2] (other stuff)
[Turn3] (other stuff)
[Turn4] (other stuff)
[Turn5] clients start interpolating towards e1
[Turn6] clients start interpolating towards e2
[Turn7] e1 target-turn: e1 should be true/fulfilled now
[Turn8] e2 target-turn: e2 should be true/fulfilled now
[Turn9] 

如果两个客户不同意某事件是什么,该怎么办?首先请注意,每个客户都可以独立检测到这一点,因为每个客户都有一个时间轴,其中在到达之前变得一致。该怎么做取决于你的应用程序以及它是什么类型的事件:

  • 有很多活动没有游戏性效果,例如如果您的物理引擎计算的东西只是为了更好的图形。那些事件可以被遗忘。
  • 对于其他活动,只要两个客户同意,一个或另一个版本就会得到满足。客户端可以基于某种启发式分散地选择版本(无需通信)。
  • 在其他情况下,可能会发生事件A使事件B无效以及B使A无效:在这种情况下,您可以让服务器决定并重新安排以后的另一个X ms。