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

mac*_*ack 5 synchronization network-programming

我正在为在网络上玩的两个玩家写一个简单的在线乒乓球游戏.它是一个客户端 - 服务器应用程序,在服务器端具有游戏逻辑.我在客户端有一些游戏同步问题,结果非常不满意.这是它目前的工作方式:

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

这种方法不能很好地工作,因为它在客户端来回移动游戏对象.任何想法如何改进它?

Pie*_*rre 17

承认客户端和服务器之间的延迟为30毫秒.客户发送"我想把我的球拍向下移动",它的球拍是y = 100px,速度为0.1px/ms

30秒后:

  • 客户球拍在y = 100 + 30*0.1 = 103px
  • 服务器从客户端接收订单并开始移动球拍(当前在服务器端仍然是y = 100px)

20毫秒后:

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

30秒后:

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

此时,客户端球拍从108跳转到102px ......

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

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

当客户端上的效果几乎与结果无关并且无法"回滚"时,将使用第一个方法.例如:当一个客户射击导弹时,它不能说明这个导弹在下一次更新时被服务器压制,因为客户实际上没有更多的导弹库存.所以在这种情况下,客户端应用程序只会在服务器发送确认后启动导弹.

第二个用于在服务器同步时避免这些"跳转".您必须监视网络延迟以预测游戏元素的移动.这里有两种方法:在启动时计算ping或同步服务器和客户端时间(最简单,更健壮的方式).一般的想法是:

  • 客户发送"我想在时间= 1265871时移动我的球拍"并开始移动

30ms后:

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

完善!他们是同步的.

20ms后:

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

30ms后:

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

同样,客户端和服务器同步!

当第一个客户端停止移动时,可以在另一个客户端上执行Desync.在这种情况下,球员球拍将"跳跃"一点点.如果这不重要,可以平滑这种转变.

希望它会有所帮助.