【问题标题】:MultiPlayer - Server communication, what to transferMultiPlayer - 服务器通信,传输什么
【发布时间】:2026-01-07 16:50:01
【问题描述】:

正如标题所暗示的,我目前正在尝试创建一个小型多人游戏作为一个项目,只是为了更多地了解所需的所有技能。

所有这些都在 Java 中实现: 我不确定如何处理服务器通信。目前我的世界对象被保存为一个包含自写类“实体”的 ArrayList。它是通过将实体中的每个图像根据其坐标绘制到框架来显示的。所有这些都很好。问题来了:

随着世界的每一次变化,例如任何实体的移动,我应该将整个 ArrayList 实体传输给每个玩家,我应该只发送更改然后只更新更改的实体,还是应该将世界保存在服务器上而不是本地 mashine 并发送导致的输入变化,例如WASD 用于玩家移动?

我想我读过一些关于外包给本地机器的文章,但另一方面,我认为如果一切都发生在服务器而不是客户端上,那么世界信息的传输会更快。

提前致谢

【问题讨论】:

    标签: java sockets software-design multiplayer game-theory


    【解决方案1】:

    在多人游戏中,速度是第一要务。任何以某种方式增加开销、减慢速度、需要加载或永久传输大数据块的事情都应不惜一切代价避免。

    我肯定会将世界坐标和东西保存在服务器上,而纹理和模型等应该保留在客户端上。 现在客户端可以加载世界并在那里注入所有东西,构建一个漂亮的 gui,所有这些东西。这不会绘制网络连接。 但是,服务器必须知道每个 3d 对象的四分之一(假设您使用 3d),所以 f.e. :

    PLAYER_A:
    posX : 3,
    位置:3,
    位置:4,
    rotX : 30°,
    旋转 : 60°,
    rotZ : 10°

    为了避免向服务器发送 6 条消息(然后服务器将其广播给其他玩家),我们发明了四元数(6 维对象)。但我怀疑 java 可以开箱即用,所以你必须自己想出一个解决方案。您还应该考虑诸如“forwardspeed”和“jumpvelocity”之类的东西,因为在客户端的机器上进行计算更容易。

    现在,抓取一个对象,无论您如何调用它,并将其发送到服务器。

    服务器现在知道“玩家 a 在 xyz,面向 abc”。
    然后服务器将其转发给其他玩家,他们希望及时获得信息(因此请始终尝试使用 UDP 并忽略数据包丢失),并将在他们这边计算和动画。

    如果延迟足够小(即 20 毫秒 f.e.),玩家将“实时”体验到这一点(尽管没有真正的实时)

    Tl;dr : 始终尝试尽可能少地向服务器发送,并让服务器将其广播给客户端。然后他们可以自己“重新计算”动画。

    编辑: 当然,您还需要一种定期将世界对象信息发送到服务器的 update() 例程,所以 f.e.树的位置等。虽然客户端可以在这些实体看不见时消失(我真的鼓励你这样做),但服务器仍然需要知道完整的地图布局(也就是说,没有纹理和东西,这很快就会变得很大)

    【讨论】:

    • 这超出了我的预期,谢谢。它肯定会对我有很大帮助。我没有想过让动画和其他东西在客户端上计算,但这更有意义。谢谢!