如何序列化JBox2d World对象?

时间:2013-10-07 22:54:25

标签: java json serialization objectoutputstream jbox2d

我有一台连接多个客户端的服务器。每个客户都有一个他们可以控制的身体(玩家),但是可能会发生碰撞,因此他们需要看到其他人的身体才知道为什么他们的一些动作受到限制。

我的解决方案是将“World”对象传递到对象in / out流中。然后我使用处理解析并绘制每个身体。这是我得到的错误:

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.jbox2d.dynamics.World
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at Client.setup(Client.java:30)
    at processing.core.PApplet.handleDraw(PApplet.java:2280)
    at processing.core.PGraphicsJava2D.requestDraw(PGraphicsJava2D.java:243)
    at processing.core.PApplet.run(PApplet.java:2176)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.io.NotSerializableException: org.jbox2d.dynamics.World
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at Player.sendWorld(Player.java:57)
    at Server.draw(Server.java:54)
    at processing.core.PApplet.handleDraw(PApplet.java:2305)
    ... 3 more

显然,在通过套接字传递之前,World需要序列化/可序列化。知道我该怎么做吗?我是否需要为每个身体做一下,创建xml / json然后传递它而不是简单地发送世界?

服务器输出

public void sendWorld(World world) {
    try {
        out.writeObject(world);
        out.flush(); // or maybe out.reset()
    } catch (IOException e) {
        e.printStackTrace();
    }
}

客户端

try {
    bodySocket = new Socket(serverHostname, port);
    in = new ObjectInputStream(bodySocket.getInputStream());
    Object next = in.readObject();
    System.out.println("Getting world");
    if (next instanceof World) {
        this.world = (World) next;
    }
} catch (UnknownHostException e) {
    System.err.println("Don't know about host: " + serverHostname);
    System.exit(1);
} catch (IOException e) {
    System.err.println("Couldn't get I/O for " + "the connection to: "
            + serverHostname);
    e.printStackTrace();
    System.exit(1);
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

客户端抽奖

public void draw() {
    // Background
    background(100);
    // Bodies (includes floors, walls, and players)
    for (Body body = world.getBodyList(); body != null; body = body
            .getNext()) {
        Vec2 playerLoc = body.getPosition();
        rectMode(PApplet.RADIUS);
        fill(255, 100);
        rect(playerLoc.x, fieldBottom - playerLoc.y, 10, 10);
    }
}

2 个答案:

答案 0 :(得分:2)

由于这个原因,我制作了序列化包:)

我将序列化包含到protobufs中,这对你来说可能是最好的东西(它最大限度地减小了大小)。您可以序列化世界,实体,关节,形状,以及您想要的任何粒度。

查看PbSerializer

这里有关于protobufs的文档: https://code.google.com/p/protobuf/

答案 1 :(得分:0)

您可以查看JBbSerializer类。从它的javadoc:“jbox2d的序列化器,用于序列化物理世界的任何方面,”所以它可能会做你想要的。在jbox2d-serialization项目中寻找它(应该随你下载)。不过,这可能比它的价值更麻烦。