Java - 序列化对象中序列化对象的问题

时间:2013-08-22 10:13:02

标签: java serialization

嘿所有我正在为一场游戏制作游戏,我通过研究和阅读解决了大部分问题,但现在我已经陷入困境。

游戏的快速解释: 两个客户端连接到服务器并启动游戏。服务器执行所有计算,并在每个周期向客户端发送一个序列化的GameState对象。 GameState只是一堆变量,显示了玩家的位置以及一些吸气者/制定者。这很好用。但是,现在我在游戏状态中制作了一个导弹阵列列表,导弹是一个单独的对象,也是可序列化的。客户端和服务器都具有GameState类和Missile类的相同副本。

当客户端按下空格时,会添加导弹,并且此服务器会注册这些内容。我让服务器在gamestate的服务器版本中打印导弹数量。在客户端打印导弹数量始终为零。以下是我试图仅将相关内容放入的一些代码。

服务器将对象发送到播放器,player.objectout只是将对象写入objectoutputstream

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

GameState的主要部分(省略了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();
}

最后客户端读到的地方。 panel是一个JPanel,使用gamestate获取drawimages的位置

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

另外在相关的说明中(可能是我的主要问题的原因),在我链接的代码的第一部分中,我必须创建一个全新的GameState对象来发送。为什么是这样?如果我尝试只发送gameState变量strightup,则不会保留任何信息。谢谢:))

1 个答案:

答案 0 :(得分:1)

所以,如果我理解正确,服务器有一个游戏状态,序列化它,然后发送给玩家。然后玩家修改他们收到的游戏状态的内容,并且您对服务器上的游戏状态不包含更新感到惊讶。

这是预期的。序列化不会发送对象的远程引用。它将对象转换为字节序列,发送此字节序列,然后由接收器从字节序列重构对象。

要进行类比,使用序列化发送对象就像拿纸质文档并传真一样。无论接收方在接收的传真上写入什么内容,都不会神奇地出现在原始文档中。

如果您希望服务器知道更改,客户端必须将更新发送到服务器。

关于问题的最后部分,如果我理解正确,你试图将同一个对象多次发送到同一个ObjectOutputStream,并且接收者没有看到第一个对象状态和后续对象状态之间的任何差异。这也是预期的。第二次发送相同的对象仅发送对先前发送的对象的引用。这对于支持多次引用同一对象的对象图是必要的。您需要调用reset()来重置流并能够发送已发送对象的新状态。