简单的在线乒乓球游戏网络同步
我正在为两个通过网络玩游戏的玩家编写一个简单的在线乒乓游戏。它是一个客户端-服务器应用程序,游戏逻辑位于服务器端。我在客户端的游戏同步方面遇到了一些问题,结果很不令人满意。这就是它目前的工作方式:
- 在服务器端,我有一个游戏对象,用于存储玩家和球的位置,每个对象都有其 x、y 位置和 x、y 速度。基于该对象的位置在循环中更新。 在客户端有相同的本地对象具有相同的数据,并且它也在循环中更新。
- 当玩家按下/释放向上或向下时,客户端发送一个带有一个整数的网络数据包,以便玩家对象开始/停止在服务器上的游戏对象中移动。
- 服务器每 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:
- 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. - 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.
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
承认客户端和服务器之间有 30 毫秒的延迟。
客户端发送“我想将球拍向下移动”,其球拍位于 y=100px,速度为 0.1px/ms
30ms 秒后:
(目前服务器端仍处于 y=100px)
20ms 秒后:
30ms 秒后:
此时,客户端球拍从 108 向后“跳”到102px...
如何应对网络延迟?
两种互补方法:
第一种方法用于当对客户端的影响与结果几乎没有联系且无法确定时。 “回滚”。示例:当客户端发射导弹时,不可承认该导弹在下次更新时被服务器抑制,因为客户端实际上没有更多的导弹库存。因此在这种情况下,客户端应用程序只有在服务器发送确认后才会发射导弹。
第二个始终用于避免服务器同步时的这些“跳跃”。您必须监控网络延迟才能预测游戏元素的移动。这里有两种方法:计算 ping 或在启动时同步服务器和客户端时间(最简单且更可靠的方法)。
总体思路是:
在 30 毫秒后开始移动:
完美!它们是同步的。
20 毫秒后:
30 毫秒后:
再次,客户端和服务器同步!
当第一个客户端停止移动时,另一个客户端上可能会发生异步。在这种情况下,球员的球拍会稍微“跳跃”。当这并不重要时,可以平滑此过渡。
希望它会有所帮助。
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:
(which is currently still at y=100px on the server side)
20ms seconds later:
30ms seconds later:
At this point, the client racket "jumps" backward from 108 to 102px...
How to cope with the network latency?
Two complementary ways:
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:
30ms later:
Perfect! They are synchronized.
20ms later:
30ms later:
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.