2011-09-28 110 views
7

對於一個學校項目,我們應該創建一個Java遊戲(它應該是客戶端/服務器),可以通過互聯網進行多人遊戲(我們在學校編程,所以這不是作業)。遊戲是基於回合的,但應該有一個聊天,這是實時的。然而,我們都沒有網絡編程方面的經驗,而且我對它的瞭解越多,我似乎也有更多的問題。Java多人遊戲 - 網絡概念

我的第一個想法是使用套接字API來實現多人部分。服務器等待來自客戶端的新數據。但是,有多種類型的數據可供接收,如聊天消息,移動等。另外,一旦與服務器建立連接,應發送一些初始數據(如播放機的名稱)。服務器應該能夠看到它收到的是什麼類型的消息,但是如何?我正在考慮用字符串字段type創建類Message。但在我的服務器代碼,我會得到這樣的代碼:

在有很多不同類型的數據的發送(會有),這看起來並不像最有效的方式。此外,這意味着服務器和客戶端都應該有這個消息類/接口(重複代碼)。

其他遊戲的東西呢?例如,玩家1將他的角色移動到擊敗另一個角色的位置。玩家1的客戶計算這種失敗並應用正確的動作。但是應該發送給服務器的是什麼?只是新玩家的位置或失敗?有了第一個選項,這意味着所有其他客戶都應該進行計算。這不會造成什麼麻煩嗎?由於我之前沒有網絡編程經驗,所以我對如何完成所有這些事情感到困惑。

我也讀過另一個線程在這裏Stackoverflow RMI可能是一個更好的選擇。閱讀了一些有關這方面的信息後,我瞭解了RMI是什麼,但我仍然無法確定它是否適合此項目。任何提示爲此?

正如你所看到的,我對如何從這個項目的網絡部分開始有點困惑。我搜索了一些遊戲編程書籍(對於Java而言),但他們都不關注網絡部分。我還搜索了Java網絡書籍,但是這些似乎集中在技術上,而不是良好的代碼實踐。

如果有人知道一本好書或在正確的鍛鍊方面有一些建議,將不勝感激。

感謝

+7

「...在學校編程,所以它不是功課」 。經典。 – CPerkins

+0

至少他不想要代碼。 –

+0

@ CPerkins:我們應該在學校爲這個項目工作,是的。我並沒有要求任何人做我的工作,只是詢問如何實施這一點。 – Bv202

回答

7

你是在正確的道路上,但也有幾件事情需要清理。

如果你使用套接字,你已經發現你需要定義一個協議 - 一種溝通移動和遊戲狀態的相互語言。套接字將允許您以任何您想要的格式發送任何類型的數據。它看起來像在考慮序列化一個類Message來發送這種類型,這是一個做事情的過程。如果你使用RMI(它有自己的協議),你會像調用Java方法那樣工作,但實質上你正在做類似的事情,序列化數據並通過套接字傳遞它。

關於在客戶端和服務器之間共享代碼沒有任何明顯的錯誤 - 事實上,大多數服務都以某種形式做到這一點。您的客戶端和服務器都可以使用通用庫來定義傳遞的消息類。 RMI使用方法存根來確定接口。各種Web服務定義瞭如何調用方法。總的想法是隻暴露接口,而不是實現。

關於您的代碼,對於每種消息類型都可能有更清晰的消息子類,並且可以爲每條消息添加其他參數。然後你可以有一個MessageProcessor的類,如:

class MessageProcessor{ 
    void process(Move1Message m) {...} 
    void process(Move2Message m) {...} 
    .... 

} 

至於送什麼 - 總的原則應該是在客戶端負責發送其移動到服務器,別的它是一個獎金,因爲服務器需要驗證移動的合法性。服務器應該始終是遊戲狀態的決定因素,以避免作弊和錯誤的客戶端實現

除非您有興趣學習如何實現自己的協議或使用Java套接字庫,否則它會更容易使用RMI。您也可以使用SOAP,REST或任何其他協議,但我不打算考慮現在要使用哪一個。我沒有任何超出the RMI documentation的建議,但我認爲this book有很多網絡代碼示例。

0

與插座去當每個客戶都會有它自己的連接上服務器線程將等待(不要忘記刷新客戶端上的數據流,否則你會永遠等待)

每條線將是一個單獨的消息,並區分消息類型,您可以在每條消息的開始處使用「標題」(在開始時具有特定的3個字符的序列),如msg,mov,lgn,並使用帶開關的trie式選擇來快速決定哪一個你得到


wh在使用RMI時,您可以讓服務器保留一個管理器對象(在註冊表中導出並註冊),客戶端可以在該對象上請求一個「連接」對象,該對象將與套接字實現中的連接相同,但您可以有一個方法,你想做的每件事情,雖然回調將需要以其他方式完成(與你有一個連接準備好的插座)