2013-08-22 153 views
0

嘿,我正在製作一款遊戲,因爲我通過研究和閱讀來解決大多數問題,但現在我卡住了。Java - 序列化對象中的序列化對象的問題

快速解說遊戲: 兩個客戶端連接到服務器和遊戲開始。服務器執行所有計算,並在每個週期向客戶端發送一個序列化的GameState對象。 GameState只是一堆顯示玩家位置和一些吸氣/定位者的變量。這工作正常。然而,現在我已經在gamestate中製作了一個導彈陣列列表,導彈是一個單獨的對象,也是可序列化的。客戶端和服務器都有相同的GameState類和導彈類。

當客戶端按下空間時會添加導彈,並且這樣做會被服務器註冊。我讓服務器打印服務器版本的gamestate中導彈的數量。在客戶端打印導彈數量始終爲零。這裏有一些代碼,我試圖把相關的東西只在。

服務器發送對象的球員,player.objectout只是將對象寫入ObjectOutputStream中

public void updatePlayerOutput(){ 
    GameState send = new GameState(gameState); 
    leftPlayer.playerObjectOut(send); 
    rightPlayer.playerObjectOut(send); 
} 

遊戲狀態的主要部分(冷落的getter和setter)。左,右= PLAYER1和player2

public class GameState implements Serializable { 

private double leftX; 
private double leftY; 
private double rightX; 
private double rightY; 
private ArrayList<Missile> missiles; 

public GameState(){ 
    missiles = new ArrayList<Missile>(); 
} 

public GameState(GameState game){ 
    leftX = game.getLeftX(); 
    leftY = game.getLeftY(); 
    rightX = game.getRightX(); 
    rightY = game.getRightY(); 
    missiles = game.getMissiles(); 
} 

導彈類

public class Missile implements Serializable { 

private double x; 
private double y; 

private double dX; 

public Missile(double inX, double inY, double inDX){ 
    x = inX; 
    y = inY; 
    dX = inDX; 
} 

public Missile(Missile inMissile){ 
    x = inMissile.getX(); 
    y = inMissile.getY(); 
    dX = inMissile.getDX(); 
} 

最後在客戶端讀取。面板是一個JPanel,並使用遊戲狀態得到地點drawimages

while(true){ 
    gameState = (GameState)(ois.readObject()); 
    panel.setGameState(gameState); 
    panel.repaint(); 
    updateOutput(); 
    } 

而且在一個相關的說明(可能是我的主要問題的原因),在代碼的第一部分我聯繫我要創建一個全新的要發送的GameState對象。爲什麼是這樣?如果我嘗試發送gameState變量strightup,則不會保留任何信息。謝謝:)

回答

1

所以,如果我理解正確,服務器有一個遊戲狀態,將其序列化併發送給玩家。玩家然後修改他們收到的遊戲狀態的內容,並且您驚訝於服務器上的遊戲狀態不包含更新。

這是預期的。序列化不會向對象發送遠程引用。它將對象轉換爲一個字節序列,發送這個字節序列,然後由接收器從字節序列重建對象。

作爲一個類比,使用序列化發送對象就像拿紙質文檔並傳真。無論接收方在收到的傳真上寫什麼都不會奇蹟般地出現在原始文件上。

如果您希望服務器知道更改,則客戶端必須將更新發送到服務器。

關於問題的最後部分,如果我理解正確,您嘗試多次將相同的對象發送到同一個ObjectOutputStream,並且接收器沒有看到第一個對象狀態和後續對象之間的任何區別。這也是預料之中的。第二次發送相同的對象只發送對先前發送的對象的引用。這對支持多次引用同一對象的對象的圖形是必需的。您需要撥打reset()來重置流,並能夠發送已發送對象的新狀態。

+0

aaah no。客戶端通過InputStream將服務器更新爲BufferedReader。例如,如果玩家按下左箭頭,則「LEFT」被髮送到服務器,服務器更新它的gamteState以將玩家向左移動。服務器然後將這個gameState的副本發送給兩個玩家。客戶端從不更新遊戲狀態,只是用它來獲取玩家/導彈的位置等。我故意這樣做了這樣的事情,以便只有服務器才能修改遊戲,使其更加安全 –

+0

因此,客戶端代碼在哪裏發送更新以及接收來自玩家的變化並更新遊戲狀態的服務器代碼,因爲那是問題出現的地方? –

+0

感謝您解決第二部分!因爲我離開了我的電腦,所以我不能給ATM代碼。這似乎很奇怪,但如果這是問題,但。當我運行遊戲時,我可以移動兩個玩家沒有任何問題,當我按空間導彈獲得添加到服務器的遊戲狀態。 –