2013-10-07 54 views
1

我有一個服務器,有幾個客戶端連接。每個客戶都有一個他們可以控制的身體(球員),但可能會發生碰撞,因此他們需要看到其他人的身體知道爲什麼他們的一些動作受到限制。如何序列化JBox2d World對象?

我的解決方案是通過對象輸入/輸出流傳遞「世界」對象。然後我使用處理來解析和繪製每個物體。這裏是我得到的錯誤:

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 

顯然世界需要序列化/序列化之前,它可以通過套接字傳遞。任何想法我會怎麼做?我需要爲每個身體做些什麼,創建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); 
    } 
} 
+0

如果我不能算出這個很快,我可能最終會通過世界機構名單迭代並創建一個JSON對象持有用戶數據,座標和每個主體的對象類型。將更有效的網絡,但不容易寫。 –

回答

0

你可以看看在JBB串行器類。從javadoc:「用於jbox2d的串行器,用於序列化物理世界的任何方面」,因此它可以做你想要的。在jbox2d-serialization項目中查找它(應該在下載時附帶)。不過,這可能比它的價值更麻煩。

+0

謝謝,這可能會工作... PbSerializer pbs = new PbSerializer(); Builder obj = pbs.serializeWorld(world);然後客戶端\t \t \t \t如果(下一的instanceof生成器){ \t \t \t \t \t this.world = pbd.deserializeWorld((PbWorld)下一個)上; –

2

我做了系列化包裝由於這個原因:)

我包括系列化protobufs,這可能是你最好的東西(它減少了大小最)。你可以序列化世界,身體,關節,形狀,無論你想要的粒度。

退房PbSerializer

這裏是protobufs文檔: https://code.google.com/p/protobuf/

+0

我無法讓它工作。帶有示例的所有文檔似乎都是針對C++而不是java。我嘗試了幾件事情,最終放棄了。應該真的有一個像C#這樣的頁面,它不僅提供了可用的方法,而且還提供瞭如何使用它們的簡短示例。 –

+0

該文檔是在C++和Java,再次檢查: https://developers.google.com/protocol-buffers/docs/javatutorial :) 或者更重要的是,你真的不擔心製作協議緩衝區,因爲我已經這樣做了。只需使用我在jbox2d-serialization包中創建的PbSerializer和PbDeserializer類。 –

+0

感謝您的回覆。我看了一下你鏈接到的頁面,但沒有看到任何有關Java中序列化的例子。也許我只是錯過了它。我看到了一些方法,但沒有看到它們的使用方式和期望。我確實嘗試過PS和PD課程,但是當我最終完成編譯時,我的對象編寫者會通過它。我最終編寫了自己的JSON解析器,但我很想看到從服務器傳遞到客戶端的世界對象的骨架示例!我很好奇,如果你決定通過套接字發送一個字符串或一個對象。 –