2012-07-28 90 views
-1

作爲學習實驗的一部分,我想製作一個網絡應用程序。我仍然在學習多線程,並且我製作了一個簡單的多線程「遊戲」,它涉及在屏幕上繪製精靈,玩家可以在其中移動它們。Java網絡遊戲(可能使用NIO)

對於這個新項目,我想簡單一些,只是爲了體驗和學習。我想創建一個服務器,其中多個客戶端可以連接到它。服務器將包含「遊戲對象」,它只是一個包含x和y位置,字符串名稱,識別它的ID和速度(dx和dy)的對象。

「服務器」應用程序將具有諸如工作線程更新對象位置(使用它們的速度)的功能,並且還會向客戶端發送所有遊戲對象的「狀態」,以便客戶端可以繪製它們供玩家看。

只要玩家按下鍵盤上的按鈕並生成KeyEvent,客戶端也會發送服務器數據。服務器將讀取這些數據並通過更新玩家的遊戲對象來處理它。例如,如果玩家按下左箭頭鍵,則客戶端將發送服務器數據,指示左鍵被按下,服務器將查找與客戶端關聯的遊戲對象(也許我會將對象存儲在Map中,如? )

問題是如何做到這一點。我從來沒有做過任何這種規模的網絡。到目前爲止,我所做的最多的是一個有問題的雙人遊戲。由於這是基於回合的,所以我現在試圖製作的應用程序非常不同。作爲研究,我閱讀了關於Oracle的整個併發課程。我還閱讀了關於NIO的這個教程。我以前從未使用過NIO,但我被多人推薦使用它。通過閱讀代碼並瞭解它的工作原理,我學到了很多關於多線程和併發的知識。

由於SocketChannel使用ByteBuffers進行通信,我想到的一個策略是獲取GameObjects列表並將其序列化爲一個字節數組。然後用ByteArray創建一個ByteBuffer並將其發送給客戶端。然後客戶端將獲得加載到服務器中的所有GameObjects,並能夠根據它們的類型和狀態來繪製所有的GameObjects。與此有關的一個問題是字節數​​組可能變得非常大。我用256個GameObjects進行了測試,並得到了一個高達9KB的字節數組。如果我壓縮字節數組,大小約爲96字節。不過,我不知道這是否太大,無法每秒發送15次到客戶端。

我知道的另一個選擇是按字節發送信息字節。例如,發送的第一個字節可以識別我發送的遊戲對象的類型(例如:cat,car,person),接下來的兩個字節可以識別X位置,然後接下來的兩個Y位置,然後使用最後一個字節來識別對象的狀態。使用這些數據,客戶可以在收到的位置上繪製一個精靈。

我所說的一切的一個大問題是,客戶端將無法與任何對象進行交互。客戶端將能夠發送簡單的命令到服務器,並在其位置「查看」遊戲對象的精靈。如果服務器想要告訴遊戲對象執行特定動作,那麼很難繪製它,因爲我只是將靜態精靈畫到屏幕上,而不是與精靈進行交互。

我也不確定NIO是否是最好的主意。大多數我討論過的人都會推薦它,但我不太瞭解實現非阻塞NIO服務器和多線程常規java.net。*服務器之間的實際區別。我的猜測是非阻塞服務器比多線程服務器有更好的性能,而且我只會遇到更少的問題,只有1個線程而不是每個連接多個線程。

最後,我得到了不論是否使用TCP或UDP的混合建議。我從來沒有使用過UDP。一些強烈建議TCP,而另一些強烈建議UDP。

正如你所看到的,我相當無組織,不知道該怎麼做。我覺得我已經閱讀了很多關於網絡和併發性的知識,而且我已經足夠了解Swing製作圖形遊戲。我只是不知道如何把它放在一起。

+0

tldr;你可能想要打破這個問題/提出更具體的問題 – Toby 2012-07-30 09:47:21

回答

0

也許考慮使用Netty。我發現它對快速應用程序開發非常有用,並且對於大多數服務器和客戶端應用程序來說足夠快。通過使用Java NIO的反應器設計模式的原始實現,您可以獲得更快的速度,但是它會花費更多的工作量和難以調試的代碼。