2013-08-22 155 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代码。这似乎很奇怪,但如果这是问题,但。当我运行游戏时,我可以移动两个玩家没有任何问题,当我按空间导弹获得添加到服务器的游戏状态。 –