Java网络游戏(可能使用NIO)



作为学习实验的一部分,我想制作一个网络应用程序。我还在学习多线程,我已经制作了一个简单的多线程"游戏",包括在屏幕上绘制精灵,玩家可以在其中移动它们。

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

"服务器"应用程序的功能包括工作线程更新对象的位置(使用它们的速度),它还将向客户端发送所有游戏对象的"状态",这样客户端就可以绘制它们供玩家查看。

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

问题是如何做到这一点。我以前从未做过这种规模的社交活动。到目前为止,我做的最多的是一个2人的井字游戏。由于这是基于回合的,所以我现在尝试制作的应用程序非常不同。作为研究,我阅读了关于Oracle的整个并发课程。我还阅读了这篇关于NIO的教程。我以前从未使用过NIO,但有很多人推荐我使用它。我从阅读代码和了解它的工作原理中学到了很多关于多线程和并发的知识。

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

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

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

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

最后,我得到了关于是否使用TCP或UDP的各种建议。我以前也从未使用过UDP。有些强烈建议使用TCP,而另一些则强烈建议使用UDP。

正如你所看到的,我很没有条理,不知道该做什么。我觉得我读了很多关于网络和并发的书,而且我已经对Swing有足够的了解来制作图形游戏。我只是不知道如何把这一切放在一起。

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

最新更新