2

首先,我想为我糟糕的英语道歉 :) 昨天我使用 Winsock 和 Allegro5 用 C++ 完成了我的第一个多人游戏(Pong)。游戏由一台服务器组成,供所有玩家和客户端使用。

每帧 (FPS = 60) 客户端将他们的 mouse_y 坐标发送到服务器,服务器分别将它们传递给对手的客户端。当我在连接到其中一台服务器的两台计算机上玩游戏时,通过本地网络它运行良好,对手的桨移动顺利。但是当我通过我的外部 IP 地址进行相同的连接时,对手的球拍滞后,这会破坏游戏,因为它是客户端检查球是否击中对手的球拍。因此,同步被破坏了,每当我在另一台计算机上移动一个桨来反弹球时,它就会滞后并且没有及时完成,从而导致对手得分......但这不是滞后的游戏。我的桨和球移动得很顺畅。问题仅在于对手的桨。

我是网络编程的新手,因为我只阅读了Beej 的网络编程指南。我使用 TCP 套接字来 send() 和 recv() 桨坐标,并使用 select() 函数来轮询套接字以获取数据。

我不知道可能是什么原因。

TL;DR:当我通过外部 IP 连接时,对手的拨片滞后,但当我通过本地 IP 连接时则没有。

4

2 回答 2

2

嗯,这是完全预期的行为,由光速强加(除其他外)。通过 Internet 发送的数据包需要一段时间才能到达:

$ ping stackoverflow.com
PING stackoverflow.com (198.252.206.16) 56(84) bytes of data.
64 bytes from stackoverflow.com (198.252.206.16): icmp_req=1 ttl=53 time=85.1 ms

这告诉我从我的机器到 stackoverflow.com 的 RTT(往返时间)为 85 毫秒,这对于网站来说还不错,但足以导致实时游戏出现明显的延迟。

这就是坏消息。更糟糕的消息是,这是一个非常难以解决的问题。

专业的实时多人游戏使用多种技巧来使延迟不那么明显。例如,他们跟踪每个客户端的延迟,并尝试“预测”玩家在当前时间点的位置,即使这些数据包尚未到达。但是当然,如​​果数据包到达并且预测结果是错误的,这将导致玩家突然“跳”到正确的地方。为了解决这个问题,他们在预测位置和最后已知位置之间应用了一些平滑。如果做得好,就会产生实时运动的错觉。

另一个问题是您不能仅在客户端上执行游戏逻辑,因为每个客户端对世界的看法都略有不同。让客户端做预测是可以的,但是服务器应该对球拍是否击球有最终决定权。

于 2013-08-03T12:30:49.173 回答
2

扩展托马斯所说的话。我会给你一个更实际的答案。

  • 使用 UDP 进行游戏。


如果您坚持使用 TCP,请执行这些操作。

  • 降低TCPAckFrequency的值。

  • 禁用nagle 的算法,因为您的请求会很小。通过将TCPNoDelay设置为 1 来实现。

  • 缓解两点之间的移动。

  • 在打包其余数据的同时发送更少的数据。

  • 将接收到的数据包转换为结构。

  • 不要使用select. 大约 50 次连接后,您会注意到huge性能下降。分别用于Windows/Linux epollIOCP

于 2013-08-03T12:57:28.870 回答