2015-10-19 84 views
3

我在使我的簡單多人遊戲起作用時存在一個小問題,它主要與等待響應的客戶端有關從服務器無限期地。遊戲大多是實時的,這就是爲什麼這個問題已經出現。在項目中將其改爲基於回合的解決方案(這將是我的最後手段)有點晚。我正在使用計時器來處理遊戲的實時情況。一切都在單人遊戲中完美運行,所以這完全是一個問題。基本上,計時器會在更新所有常用遊戲邏輯更新之前檢查來自服務器的任何消息。這是在handleServerResponses()函數中完成的。下面是定時器代碼:如何使用基本Java套接字停止(「跳過」)等待服務器響應的客戶端

timer.addActionListener(new ActionListener(){ 
     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      if(!gamePanel.getGameOver()){ 
       handleServerResponses(); 
       gamePanel.updateZombieAI(); 
       if(Math.floor(Math.random()*100)<(10+Math.ceil(gamePanel.getPlayer1Score()/10))){ 
        gamePanel.spawnZombie(); 
       } 
      } 
      else{ 
       timer.stop(); 
       sendMessage("TERMINATE"); 
      } 

     } 

    }); 

這裏是爲handleServerResponses方法的代碼的一部分:

public void handleServerResponses(){   
    try { 
     String message=inStream.readLine();<---Here is where it gets stuck 

正如你所看到的,程序卡住等待服務器發送響應,但它不會發送響應,因爲這兩個玩家都不能移動或發送消息。 inStream變量只是一個使用服務器輸入流的BufferedReader。我只是在客戶端和服務器之間傳遞文本。有什麼辦法可以跳過等待回覆嗎?意思是說,如果沒有任何東西從服務器發送過來,程序是否可以忽略該定時器的打勾並更新遊戲邏輯?我搜索了過去一小時的答案,但沒有出現。

謝謝!

+2

如果遊戲邏輯應該是基於回合的,那麼我會這樣做。但是,無論如何,在將Swing GUI與Socket I/O混合使用時,您必須考慮線程問題,主要是您必須注意您的I/O代碼不會與Swing事件線程(EDT)捆綁在一起。這與輸出部分沒有太大關係,但與輸入部分非常相關,並且出於這個原因必須在後臺線程中處理InputStream。 –

+0

非常感謝!我會給它一個鏡頭。 –

回答

1

這裏有兩種解決方案:正確的解決方案和(可能的)簡單解決方案。

正確的解決方案是做Hovercarft Full Of Eels評論,並有一個單獨的線程處理您的網絡數據。在這個模型中,你會讓你的響應處理程序讀取數據並將其添加到隊列中,並且當有/可用時,你的遊戲線程將從這個隊列中讀取數據。在這個模型中,你的遊戲線程永遠不會等待網絡數據,因爲這是IO線程的領域。

如果由於某種原因您的解決方案令人望而生畏或無法實施,那麼快速解決方案可能是在嘗試從中讀取之前調用inStream.ready()。這絕不是保證,因爲調用ready()不能確保整行可供讀取,但是如果您的服務器只響應整行,那麼它可能足以阻止您。

爲了記錄,我會強烈建議使用單獨的IO線程的第一個解決方案,它與遊戲線程解耦,因爲它更健壯。

+1

很好的答案 - 謝謝你教育我們所有人。 1+ –

+0

非常感謝你和氣墊船!我會嘗試兩種解決方案。 –

相關問題