首页 > 解决方案 > 在使用套接字制作游戏时,处理独立于所有玩家的多个对象的最有效方法是什么?

问题描述

例如,假设我有一个随机游戏,其中有 500 个独立对象和 10 个玩家。

独立对象是每次更新都会向特定方向移动的对象,无论玩家做什么(玩家无需接触这些对象)。

现在,如果玩家正在射击(比方说)子弹,那会更容易,因为它属于特定玩家,因此更容易避免游戏延迟。不过,让我们看一些更简单的东西,例如玩家尝试更新他们的位置。我会在客户端和服务器端做的典型事情是:

    client side : update the coords of the player + send a message to the server as socket X

    server side : receives the message from socket X, updates the coords of the player on the server side + 
sends a message with the coords of that same player to all other sockets

当您进行这样的交流时,每个人都会收到玩家的新坐标,并且几乎没有延迟。(对于像子弹这样的对象也足够了,因为它们是在触发玩家事件时创建的)

您如何处理 500 多个在整个地图上以随机速度沿随机方向移动的独立对象,并有效地为所有玩家更新它们?(请注意,他们的速度和速度可以在与玩家接触时改变)。到目前为止我已经尝试过:

    1) Put all of the movement + collission logic on the server side & 
notifying all clients with a setTimeout loop & io.emit - 

结果:即使您只有 500 多个对象和 4 个连接的玩家,也会导致大量延迟。所有玩家都收到服务器的响应太慢了

    2) Put all of the movement + collission logic on the client side & notifying the server about every object' position- 

结果:老实说,不会遇到太多滞后,但我不确定这是否是正确的想法,因为每次对象移动时,我实际上是从每个客户端向服务器发送一条消息以更新同一个对象(服务器正在收到关于同一对象的 N[连接客户端数量] 次通知)。完全在客户端处理这也是一个坏主意,因为当玩家随机切换选项卡 [进入非活动状态] 时,将不会在该玩家的浏览器中执行更多的 javascript,整个逻辑将中断

我还注意到像 agar.io、slither.io、diep.io 等游戏,它们并没有真正拥有数百个向各个方向移动的对象。在 agar.io 和滑行中,您主要有静态对象(食物)和玩家,在 diep.io 中有动态对象,但它们都没有以非常高的速度移动。人们如何实现这一目标?有没有什么聪明的方法可以以最小的延迟实现这一目标?

提前致谢

标签: node.jssocket.io

解决方案


将您的用户交互转换为枚举操作并转发这些操作。玩家 A 按下左箭头,客户端将其解释为“MOVE_LEFT”,并带有可能的附加属性(多少、角度等)以及从玩家 A 的角度指示此动作何时发生的时间戳。

服务器接收到此信息并将其验证为可能的操作,并将其转发给所有客户端。

然后每个客户端自己解释动作并根据玩家 A 的动作更新他们自己的模拟。

不要每次滴答都将整个游戏状态发送给每个客户端,那太臃肿了。另一方面是能够处理迟到或丢失的动作。一种方法是回滚,您保留多组状态,然后继续游戏模拟,直到找到错误解释(延迟/丢失数据包)。恢复到“正确”状态并重播所有消息,以使状态更正。这就是GGPO背后的想法。

我建议还阅读Gaffer on Games所涉及的每篇与网络相关的文章,尤其是每个程序员需要了解的关于游戏网络的知识。他们是非常好的文章。


推荐阅读