0

作为学习实验的一部分,我想做一个网络应用程序。我仍在学习多线程,并且我制作了一个简单的多线程“游戏”,其中涉及在屏幕上绘制精灵,玩家可以在其中移动它们。

对于这个新项目,我想做一些简单的事情,只是为了体验和学习。我想创建一个服务器,多个客户端可以连接到它。服务器将包含“游戏对象”,它只是一个包含 x 和 y 位置、字符串名称、标识它的 ID 和速度(dx 和 dy)的对象。

“服务器”应用程序将具有诸如更新对象位置(使用它们的速度)的工作线程之类的功能,它还将向客户端发送所有游戏对象的“状态”,以便客户端可以将它们绘制给玩家看。

每当玩家按下键盘上的按钮并生成 KeyEvent 时,客户端也会发送服务器数据。服务器将读取这些数据并通过更新玩家的游戏对象来处理它。例如,如果玩家按下左箭头键,客户端将向服务器发送指示左键被按下的数据,服务器将找到与客户端关联的游戏对象(也许我会将对象存储在 Map 中,例如? )

问题是如何做到这一点。我以前从未做过任何这种规模的网络。到目前为止,我所做的最多的是一个有缺陷的 2 人井字游戏。由于这是基于回合制的,因此我现在尝试制作的应用程序非常不同。作为研究,我阅读了关于 Oracle 的整个并发课程。我还阅读了关于 NIO 的本教程。我以前从未使用过 NIO,但我被很多人推荐使用它。通过阅读代码并弄清楚它是如何工作的,我学到了很多关于多线程和并发的知识。

由于 SocketChannels 使用 ByteBuffers 进行通信,我想到的一种策略是获取 GameObjects 列表并将其序列化为字节数组。然后使用 ByteArray 创建一个 ByteBuffer 并将其发送给客户端。然后,客户端将获取加载到服务器中的所有游戏对象,并能够根据它们的类型和状态绘制所有这些对象。这样做的一个问题是字节数​​组可能会变得非常大。我用 256 个游戏对象对其进行了测试,得到了一个高达 9KB 的字节数组。如果我压缩字节数组,大小将约为 96 个字节。不过,我不知道这是否太大而无法每秒发送给客户端 15 次。

我知道的另一个选择是逐字节发送信息。例如,发送的第一个字节可以识别我正在发送的游戏对象的类型(例如:猫、汽车、人),接下来的两个字节可以识别 X 位置,接下来的两个字节可以识别 Y 位置,然后是使用的最后一个字节来识别对象的状态。使用这些数据,客户端可以在接收到的位置上绘制一个精灵。

我所说的所有内容的一个大问题是客户端将无法与任何对象进行交互。客户端将能够向服务器发送简单的命令,并在其位置“查看”游戏对象的精灵。如果服务器想要告诉游戏对象执行特定操作,则很难绘制它,因为我只是将静态精灵绘制到屏幕上,而不是与精灵交互。

我也不确定 NIO 是否是最好的主意。我交谈过的大多数人都推荐它,但我不太了解实现非阻塞 NIO 服务器和多线程常规 java.net.* 服务器之间的实际区别。我的猜测是,非阻塞服务器比多线程服务器具有更好的性能,而且我遇到的问题要少得多,只有 1 个线程而不是每个连接多个线程。

最后,对于是否使用 TCP 或 UDP,我得到了不同的建议。我以前也从未使用过UDP。一些强烈建议使用 TCP,而另一些强烈建议使用 UDP。

正如你所看到的,我很杂乱无章,不知道该怎么做。我觉得我已经阅读了很多关于网络和并发的知识,并且我已经对 Swing 有足够的了解来制作图形游戏。我只是不知道如何把它们放在一起。

4

1 回答 1

0

也许考虑使用Netty。我发现它对于快速应用程序开发非常有用,并且对于大多数服务器和客户端应用程序来说足够快。使用 Java NIO 实现反应器设计模式的原始实现可以更快,但这需要更多的工作和难以调试的代码。

于 2012-08-02T23:42:44.240 回答