简单的在线乒乓球游戏网络同步

发布于 2024-10-12 13:09:16 字数 414 浏览 3 评论 0原文

我正在为两个通过网络玩游戏的玩家编写一个简单的在线乒乓游戏。它是一个客户端-服务器应用程序,游戏逻辑位于服务器端。我在客户端的游戏同步方面遇到了一些问题,结果很不令人满意。这就是它目前的工作方式:

  1. 在服务器端,我有一个游戏对象,用于存储玩家和球的位置,每个对象都有其 x、y 位置和 x、y 速度。基于该对象的位置在循环中更新。 在客户端有相同的本地对象具有相同的数据,并且它也在循环中更新。
  2. 当玩家按下/释放向上或向下时,客户端发送一个带有一个整数的网络数据包,以便玩家对象开始/停止在服务器上的游戏对象中移动。
  3. 服务器每 50 毫秒发送一个同步数据包,其中包含所有三个对象的位置和速度。当客户端收到此数据包时,它会相应地更改游戏对象的位置。

此方法效果不太好,因为它会在客户端来回移动游戏对象。有什么想法如何改进吗?

I'm writing a simple online pong game for two players playing over the network. It's a client-server application, with a game logic on the server side. I have some problems with game synchronization on the client side, and the result is pretty unsatisfying. This is how it currently works:

  1. On the server side I've got a game object that stores position of the players and the ball, each object has its x, y position and x,y velocity. Based on that position of the objects is updated in the loop.
    On the client side there is same local object with the same data, and it is also beeing updated in the loop.
  2. When player presses/releases up or down client sends a network packet with one integer, so that the player object starts/stops to move in the game object on the server.
  3. Server sends a synchronization packet every 50 milliseconds with position and velocity of all three objects. When client receives this packet it changes positions of the game objects accordingly.

This method doesn't work very well as it moves the game objects back and forth on the client side. Any ideas how to improve it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怂人 2024-10-19 13:09:16

承认客户端和服务器之间有 30 毫秒的延迟。
客户端发送“我想将球拍向下移动”,其球拍位于 y=100px,速度为 0.1px/ms

30ms 秒后:

  • 客户端球拍位于 y=100+30*0.1= 103px
  • 服务器收到来自客户并开始移动球拍
    (目前服务器端仍处于 y=100px)

20ms 秒后:

  • 客户端球拍位于 y=103+20*0.1 = 105px
  • 服务器端客户端球拍位于 y=100+20*0.1= 102px
  • 服务器发送到客户端新位置(102px)

30ms 秒后:

  • 客户端球拍位于 y=105+30*0.1= 108px
  • 客户端从服务器接收球拍的新位置:102px

此时,客户端球拍从 108 向后“跳”到102px...

如何应对网络延迟?
两种互补方法:

  • 在执行操作之前等待服务器确认
  • 预测操作的结果(在客户端和服务器端)

第一种方法用于当对客户端的影响与结果几乎没有联系且无法确定时。 “回滚”。示例:当客户端发射导弹时,不可承认该导弹在下次更新时被服务器抑制,因为客户端实际上没有更多的导弹库存。因此在这种情况下,客户端应用程序只有在服务器发送确认后才会发射导弹。

第二个始终用于避免服务器同步时的这些“跳跃”。您必须监控网络延迟才能预测游戏元素的移动。这里有两种方法:计算 ping 或在启动时同步服务器和客户端时间(最简单且更可靠的方法)。
总体思路是:

  • 客户端发送“我想在时间 = 1265871 时向下移动我的球拍”并

在 30 毫秒后开始移动:

  • 客户端球拍在 y=100+30*0.1= 103px
  • 服务器接收移动并计算 30 毫秒延迟(通过 ping 或时间同步差)并将球拍位置设置为 y=100+latency*0.1= 100+30*0.1= 103px

完美!它们是同步的。

20 毫秒后:

  • 服务器和客户端球拍均位于 y=103+20*0.1= 105px
  • 服务器发送新位置和方向

30 毫秒后:

  • 客户端球拍位于 y=105+30*0.1= 108px
  • 客户端接收新位置和方向(向下移动 105px) ,计算 30ms 延迟并将球拍位置设置为 y=105+latency*0.1= 105*30*0.1= 108px

再次,客户端和服务器同步!

当第一个客户端停止移动时,另一个客户端上可能会发生异步。在这种情况下,球员的球拍会稍微“跳跃”。当这并不重要时,可以平滑此过渡。

希望它会有所帮助。

Admit you have a latency of 30ms between client and server.
The client send "I wanna move my racket down" and its racket is at y=100px with a velocity of 0.1px/ms

30ms seconds later:

  • client racket is at y=100+30*0.1= 103px
  • server receives the order from the client and start moving the racket
    (which is currently still at y=100px on the server side)

20ms seconds later:

  • client racket is at y=103+20*0.1 = 105px
  • server-side client racket is at y=100+20*0.1= 102px
  • server sends to client the new position (102px)

30ms seconds later:

  • client rarcket is at y=105+30*0.1= 108px
  • client receives from server the new positon of the racket: 102px

At this point, the client racket "jumps" backward from 108 to 102px...

How to cope with the network latency?
Two complementary ways:

  • await server acknowlegment before doing an action
  • predict results of actions (on the client and server sides)

The first aproach is used when the effect on the client is hardly linked with the result and cannot be "rollback". Example: when a client shots a missile, its not addmitable that this missile is being suppressed by the server on the next update because the client had in fact no more missile stock. So in this case, client application will launch the missile only afer the server sent an acknowlegment.

The second is always used to avoid these "jumps" when server sync. You have to monitor network latency to predict movment of your game elements. Here two ways: compute the ping or synchronize server and client time at startup (the easiest and more robust way).
The general idea is:

  • client sends "I wanna move my racket down at time=1265871" and start moving

30ms later:

  • client racket at y=100+30*0.1= 103px
  • server receives the move and compute the 30ms latency (by ping or time sync difference) and set the racket position at y=100+latency*0.1= 100+30*0.1= 103px

Perfect! They are synchronized.

20ms later:

  • server and client racket both at y=103+20*0.1= 105px
  • server sends new position AND direction

30ms later:

  • client racket at y=105+30*0.1= 108px
  • client receives new position AND direction (105px moving down), computes the 30ms latency and set the racket position at y=105+latency*0.1= 105*30*0.1= 108px

Again, client and server are synchronized!

Desync can happens on the other client when the first client stop moving. In this case the player racket will "jump" a little bit. When this is not critical, it's possible to smooth this transition.

Hope it will help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文