对于2人空间场景,我启动了一个接受来自2个客户端的连接的服务器。
import java.io.IOException;
import com.jme3.app.SimpleApplication;
import com.jme3.system.JmeContext;
import com.jme3.network.ConnectionListener;
import com.jme3.network.Filters;
import com.jme3.network.HostedConnection;
import com.jme3.network.Message;
import com.jme3.network.Network;
import com.jme3.network.Server;
import com.jme3.network.serializing.Serializer;
public class SpaceWorldServer extends SimpleApplication implements
ConnectionListener {
Server myServer = null;
static SpaceWorldServer app = null;
int counter = 0;
public static void main(String[] args) {
app = new SpaceWorldServer();
app.start(JmeContext.Type.Headless);
}
public void simpleInitApp() {
System.out.println("simpleInitApp");
try {
myServer = Network.createServer(6143);
Serializer.registerClass(ActionMessage.class);
myServer.addMessageListener(new ServerListener(app),
ActionMessage.class);
myServer.addConnectionListener(this);
} catch (IOException e) {
e.printStackTrace();
}
myServer.start();
}
@Override
public void destroy() {
myServer.close();
super.destroy();
}
public void updatePlayers(Message message, HostedConnection c) {
myServer.broadcast(Filters.notEqualTo(c), message);
}
public void connectionAdded(Server s, HostedConnection c) {
System.out.println("connectionAdded:" + c.toString());
Message message = new ActionMessage(100, 200, true);
System.out.println("broadcasting message " + message.toString());
myServer.broadcast(Filters.notEqualTo(c), message);
System.out.println("broadcast message " + message.toString());
}
public void connectionRemoved(Server s, HostedConnection c) {
}
@Override
public void simpleUpdate(float tpf) {
if (counter != myServer.getConnections().size()) {
System.out.println("#connections:"
+ myServer.getConnections().size());
counter = myServer.getConnections().size();
}
}
}
我有一个客户端监听器,当第二个客户端更新时,通过服务器可以将其消息广播到第一个客户端。
import java.util.concurrent.Callable;
import com.jme3.network.Client;
import com.jme3.network.ClientStateListener;
import com.jme3.network.Message;
import com.jme3.network.MessageListener;
public class ClientListener implements ClientStateListener,
MessageListener<Client> {
private UFOSpaceWorld app;
private Client client;
private boolean doTheRoll = false;
public ClientListener(UFOSpaceWorld app, Client client) {
this.app = app;
this.client = client;
client.addClientStateListener(this);
}
public void messageReceived(Client source, Message message) {
if (message instanceof ActionMessage) {
ActionMessage helloMessage = (ActionMessage) message;
if (helloMessage.getAction() == 200) {
app.enqueue(new Callable<Void>() {
public Void call() throws Exception {
app.addNewSaucer();
return null;
}
});
} else if (helloMessage.getAction() == 1) {
if (helloMessage.isB() == true) {
doTheRoll = true;
} else {
doTheRoll = false;
}
app.enqueue(new Callable<Void>() {
public Void call() throws Exception {
if (doTheRoll == true) {
app.setDoRoll(true);
} else {
app.setDoRoll(false);
}
app.setPlayer2update(true);
return null;
}
});
}
}
}
@Override
public void clientConnected(Client arg0) {
}
@Override
public void clientDisconnected(Client arg0, DisconnectInfo arg1) {
}
}
执行并同步回调,以便在启动第二个客户端时第二个太空船出现在第一个客户端上。现在我想在第一个客户端(播放器1)的屏幕上移动第二个客户端,但是我无法将类Vector3f
序列化为播放器2移动时的方向向量。我的2个客户端使用相同的客户端类和ActionMessage类。
@Serializable()
public class ActionMessage extends PhysicsSyncMessage {
public final static int NULL_ACTION = 0;
public final static int JUMP_ACTION = 1;
public final static int ENTER_ACTION = 2;
public final static int SHOOT_ACTION = 3;
public int action = 000;
public int getAction() {
return action;
}
public void setAction(int action) {
this.action = action;
}
public boolean pressed;
public ActionMessage() {
}
String s = null;
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
boolean b = false;
public boolean isB() {
return b;
}
public void setB(boolean b) {
this.b = b;
}
public ActionMessage(String s, boolean b) {
this.s = s;
this.b = b;
}
public ActionMessage(long id, int action, boolean pressed) {
this.syncId = id;
this.action = action;
this.pressed = pressed;
this.b = pressed;
}
public ActionMessage(long id, int action, boolean pressed, boolean up) {
this.syncId = id;
this.action = action;
this.pressed = pressed;
this.b = pressed;
}
@Override
public void applyData(Object object) {
((Spatial) object).getControl(NetworkActionEnabled.class)
.doPerformAction(action, pressed);
}
}
当Vector3f无法序列化时,如何在客户端移动时发送消息?
public class UFOSpaceWorld extends SimpleApplication implements AnalogListener,
ActionListener {
private PlanetAppState planetAppState;
private Geometry mark;
private Node ufoNode;
private RigidBodyControl ufoControl;
private RigidBodyControl ufoControl2;
private Node ufoNode2;
private CylinderCollisionShape shape;
private BoundingBox bv;
private RigidBodyControl jumpGateControl;
private RigidBodyControl jumpGateControl2;
private AnimChannel channel;
private AnimControl control;
private Node spacemanNode;
private RigidBodyControl spacemanControl;
private Node alien;
private String serverName = "localhost";
private int portNumber = 6143;
private RigidBodyControl alienControl;
Spatial jumpgateSpatial;
CameraNode camNode;
ChaseCamera chaseCam;
Planet moon;
static UFOSpaceWorld app;
Client myClient = null;
Vector3f ufoDirection = new Vector3f();
Vector3f ufoDirection2 = new Vector3f();
Vector3f gate2vector = new Vector3f(10f, 10f, 1598300f);
Vector3f gate1vector = new Vector3f(10f, 10f, 1098300f);
private BulletAppState bulletAppState;
private boolean left = false, right = false, up = false, down = false,
forward = false, backward = false, attack = false, rotate = false;
private long starttime = 0;
private long playtime = 0;
private void setupChaseCamera() {
flyCam.setEnabled(false);
chaseCam = new ChaseCamera(cam, ufoNode, inputManager);
chaseCam.setDefaultDistance(2237);
}
@Override
public void destroy() {
// custom code
if (myClient != null) {
myClient.close();
}
super.destroy();
}
public static void main(String[] args) {
AppSettings settings = new AppSettings(true);
settings.setResolution(1280, 1024);
settings.setSettingsDialogImage("Interface/spacesplash.png");
settings.setTitle("Space World");
app = new UFOSpaceWorld();
if (args.length > 0) {
app.serverName = args[0];
}
if (args.length > 1) {
app.portNumber = new Integer(args[0]);
}
app.setSettings(settings);
app.start();
}
@Override
public void simpleInitApp() {
playtime = 0;
starttime = System.currentTimeMillis();
this.setDisplayStatView(false);
setDisplayFps(false);
java.util.logging.Logger.getLogger("com.jme3").setLevel(
java.util.logging.Level.SEVERE);
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(false);
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-.1f, 0f, -1f));
sun.setColor(new ColorRGBA(0.75f, 0.75f, 0.75f, 1.0f));
rootNode.addLight(sun);
// Add sky
Node sceneNode = new Node("Scene");
sceneNode.attachChild(Utility.createSkyBox(this.getAssetManager(),
"Textures/blue-glow-1024.dds"));
rootNode.attachChild(sceneNode);
// Create collision test mark
Sphere sphere = new Sphere(30, 30, 5f);
mark = new Geometry("mark", sphere);
Material mark_mat = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
mark_mat.setColor("Color", ColorRGBA.Red);
mark.setMaterial(mark_mat);
// Add planet app state
planetAppState = new PlanetAppState(rootNode, sun);
stateManager.attach(planetAppState);
// Add planet
FractalDataSource planetDataSource = new FractalDataSource(4);
planetDataSource.setHeightScale(900f);
Planet planet = Utility.createEarthLikePlanet(getAssetManager(),
293710.0f, null, planetDataSource);
planet.addControl(new RigidBodyControl(new PlanetCollisionShape(planet
.getLocalTranslation(), planet.getRadius(), planetDataSource),
0f));
planetAppState.addPlanet(planet);
rootNode.attachChild(planet);
bulletAppState.getPhysicsSpace().add(planet);
// Add moon
FractalDataSource moonDataSource = new FractalDataSource(5);
moonDataSource.setHeightScale(300f);
moon = Utility.createMoonLikePlanet(getAssetManager(), 50000,
moonDataSource);
moon.setLocalTranslation(new Vector3f(10f, 10f, 1505000f));
RigidBodyControl moonControl = new RigidBodyControl(
new PlanetCollisionShape(moon.getLocalTranslation(),
moon.getRadius(), moonDataSource), 0f);
moon.addControl(moonControl);
planetAppState.addPlanet(moon);
// add saucer
addSaucer();
jumpgateSpatial = assetManager.loadModel("JumpGate.j3o");
jumpgateSpatial.setLocalScale(10000f);
BoundingBox jbv = (BoundingBox) jumpgateSpatial.getWorldBound();
CylinderCollisionShape jshape = new CylinderCollisionShape(
new Vector3f(jbv.getXExtent(), jbv.getYExtent(),
jbv.getZExtent()), 1);
;
jumpGateControl = new RigidBodyControl(jshape, 0);
jumpgateSpatial.addControl(jumpGateControl);
jumpGateControl.setMass(0f);
jumpGateControl.setPhysicsLocation(gate1vector);
jumpGateControl.setPhysicsRotation(new Quaternion().fromAngleAxis(
90 * FastMath.DEG_TO_RAD, new Vector3f(1, 0, 0)));
Spatial jumpgateSpatial2 = assetManager.loadModel("JumpGate.j3o");
jumpgateSpatial2.setLocalScale(10000f);
BoundingBox jbv2 = (BoundingBox) jumpgateSpatial2.getWorldBound();
CylinderCollisionShape jshape2 = new CylinderCollisionShape(
new Vector3f(jbv2.getXExtent(), jbv2.getYExtent(),
jbv2.getZExtent()), 1);
;
Quaternion roll180 = new Quaternion();
roll180.fromAngleAxis(FastMath.PI / 2, new Vector3f(0, 1, 0));
jumpGateControl2 = new RigidBodyControl(jshape2, 0);
jumpgateSpatial2.addControl(jumpGateControl2);
jumpGateControl2.setMass(0f);
jumpGateControl2.setPhysicsLocation(gate2vector);
jumpGateControl2.setPhysicsRotation(new Quaternion().fromAngleAxis(
90 * FastMath.DEG_TO_RAD, new Vector3f(1, 0, 0)));
Spatial spaceStationSpatial = assetManager
.loadModel("SpaceStation.blend");
spaceStationSpatial.setLocalScale(3500f);
BoundingBox sbv = (BoundingBox) spaceStationSpatial.getWorldBound();
CompoundCollisionShape shape3 = new CompoundCollisionShape();
shape3.addChildShape(
new CylinderCollisionShape(new Vector3f(sbv.getXExtent(), sbv
.getYExtent(), sbv.getZExtent()), 1), new Vector3f(0,
0, 0));
RigidBodyControl spaceStationControl = new RigidBodyControl(shape3, 0);
spaceStationSpatial.addControl(spaceStationControl);
spaceStationControl.setMass(0f);
spaceStationControl.setPhysicsLocation(new Vector3f(10000f, -10f,
705000f));
BlenderKey blenderKey = new BlenderKey(
"objects/creatures/alien/alienmodel.blend");
Spatial alien = (Spatial) assetManager.loadModel(blenderKey);
alien.setLocalScale(20 * 2000f);
alienControl = new RigidBodyControl(3 * 500f);
alien.addControl(alienControl);
alienControl.setPhysicsLocation(new Vector3f(11000f, -50f, 755000f));
//
BlenderKey blenderKey2 = new BlenderKey(
"objects/creatures/spaceman/man.mesh.xml");
Spatial man = (Spatial) assetManager.loadModel(blenderKey2);
man.setLocalScale(200f);
spacemanControl = new RigidBodyControl(4 * 500f);
man.addControl(spacemanControl);
spacemanControl
.setPhysicsLocation(new Vector3f(10700f, -590f, 775000f));
createNewOtoBot();
BulletAppState bas = app.getStateManager().getState(
BulletAppState.class);
bas.getPhysicsSpace().addAll(spaceStationSpatial);
bas.getPhysicsSpace().addAll(man);
bas.getPhysicsSpace().addAll(alien);
bas.getPhysicsSpace().addAll(jumpgateSpatial);
bas.getPhysicsSpace().addAll(jumpgateSpatial2);
bas.getPhysicsSpace().addAll(moon);
bas.getPhysicsSpace().addAll(planet);
bas.getPhysicsSpace().setGravity(new Vector3f(0, 0, 0));
rootNode.attachChild(man);
rootNode.attachChild(alien);
rootNode.attachChild(spaceStationSpatial);
rootNode.attachChild(jumpgateSpatial);
rootNode.attachChild(jumpgateSpatial2);
rootNode.attachChild(moon);
setupChaseCamera();
registerInput();
try {
System.out.println("connecting to " + serverName);
myClient = Network.connectToServer(serverName, portNumber);
System.out.println("connected to " + serverName);
Serializer.registerClass(ActionMessage.class);
myClient.addMessageListener(new ClientListener(app, myClient),
ActionMessage.class);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (myClient != null) {
myClient.start();
} else {
System.out.println("myClient == null " + serverName);
}
}
public void clientConnected(Client c) {
System.out.println("clientConnected ");
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
public void addSaucer() {
ufoNode = (Node) assetManager.loadModel("usaucer_v01.j3o");
ufoNode.setLocalScale(200f);
BoundingBox bv = (BoundingBox) ufoNode.getWorldBound();
CylinderCollisionShape shape = new CylinderCollisionShape(new Vector3f(
bv.getXExtent(), bv.getYExtent(), bv.getZExtent()), 1);
ufoControl = new RigidBodyControl(shape, 500f);
ufoNode.addControl(ufoControl);
System.out.println("addSaucer 200:");
ufoControl.setPhysicsLocation(new Vector3f(10850f, -5979f, 785020f));
BulletAppState bas = app.getStateManager().getState(
BulletAppState.class);
bas.getPhysicsSpace().addAll(ufoNode);
rootNode.attachChild(ufoNode);
}
public void addNewSaucer() {
ufoNode2 = (Node) assetManager.loadModel("usaucer_v01.j3o");
ufoNode2.setLocalScale(700f);
bv = (BoundingBox) ufoNode2.getWorldBound();
shape = new CylinderCollisionShape(new Vector3f(bv.getXExtent(),
bv.getYExtent(), bv.getZExtent()), 1);
ufoControl2 = new RigidBodyControl(shape, 500f);
ufoNode2.addControl(ufoControl2);
ufoControl2.setPhysicsLocation(new Vector3f(10850f, -5979f, 785020f));
ufoControl2.setGravity(Vector3f.ZERO);
ufoControl2.setLinearVelocity(Vector3f.ZERO);
ufoControl2.clearForces();
BulletAppState bas = app.getStateManager().getState(
BulletAppState.class);
bas.getPhysicsSpace().addAll(ufoNode2);
rootNode.attachChild(ufoNode2);
}
public void createNewOtoBot() {
BlenderKey otoblenderKey = new BlenderKey("Models/Oto/Oto.mesh.xml");
Spatial otoBot = (Spatial) assetManager.loadModel(otoblenderKey);
otoBot.setLocalScale(600f);
RigidBodyControl otoControl = new RigidBodyControl(30 * 500f);
otoBot.addControl(otoControl);
otoControl.setPhysicsLocation(new Vector3f(10800f, -579f, 785000f));
control = otoBot.getControl(AnimControl.class);
channel = control.createChannel();
for (String anim : control.getAnimationNames())
System.out.println("otoBot can:" + anim);
channel.setAnim("pull");
BulletAppState bas = app.getStateManager().getState(
BulletAppState.class);
bas.getPhysicsSpace().addAll(otoBot);
rootNode.attachChild(otoBot);
}
public void registerInput() {
inputManager.addMapping("moveForward", new KeyTrigger(keyInput.KEY_UP),
new KeyTrigger(keyInput.KEY_W));
inputManager.addMapping("moveBackward", new KeyTrigger(
keyInput.KEY_DOWN), new KeyTrigger(keyInput.KEY_S));
inputManager.addMapping("moveRight",
new KeyTrigger(keyInput.KEY_RIGHT), new KeyTrigger(
keyInput.KEY_D));
inputManager.addMapping("moveLeft", new KeyTrigger(keyInput.KEY_LEFT),
new KeyTrigger(keyInput.KEY_A));
inputManager.addMapping("moveUp", new KeyTrigger(keyInput.KEY_E));
inputManager.addMapping("startServer", new KeyTrigger(keyInput.KEY_M));
inputManager.addMapping("moveDown", new KeyTrigger(keyInput.KEY_Q));
inputManager.addMapping("toggleRotate", new MouseButtonTrigger(
MouseInput.BUTTON_LEFT));
inputManager.addMapping("rotateRight", new MouseAxisTrigger(
MouseInput.AXIS_X, true));
inputManager.addMapping("rotateLeft", new MouseAxisTrigger(
MouseInput.AXIS_X, false));
inputManager.addMapping("rotateUp", new MouseAxisTrigger(
MouseInput.AXIS_Y, true));
inputManager.addMapping("rotateDown", new MouseAxisTrigger(
MouseInput.AXIS_Y, false));
inputManager.addListener(this, "moveForward", "moveBackward",
"moveRight", "moveLeft", "moveUp", "moveDown");
inputManager.addListener(this, "rotateRight", "rotateLeft", "rotateUp",
"rotateDown", "toggleRotate", "startServer");
// Toggle mouse cursor
inputManager.addMapping("TOGGLE_CURSOR", new MouseButtonTrigger(
MouseInput.BUTTON_LEFT), new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(actionListener, "TOGGLE_CURSOR");
// Toggle wireframe
inputManager.addMapping("TOGGLE_WIREFRAME", new KeyTrigger(
KeyInput.KEY_T));
inputManager.addListener(actionListener, "TOGGLE_WIREFRAME");
// Collision test
inputManager.addMapping("COLLISION_TEST", new MouseButtonTrigger(
MouseInput.BUTTON_RIGHT));
inputManager.addListener(actionListener, "COLLISION_TEST");
}
public void toggleToFullscreen() {
GraphicsDevice device = GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice();
DisplayMode[] modes = device.getDisplayModes();
int i = 0; // note: there are usually several, let's pick the first
settings.setResolution(modes[i].getWidth(), modes[i].getHeight());
settings.setFrequency(modes[i].getRefreshRate());
settings.setBitsPerPixel(modes[i].getBitDepth());
settings.setFullscreen(device.isFullScreenSupported());
app.setSettings(settings);
app.restart(); // restart the context to apply changes
}
long time = 0;
public void simpleUpdatePlayer2(float tpf) {
System.out.println("LOOP simpleUpdatePlayer2 player 2");
int speed = 8000;
Vector3f camDir = cam.getDirection().clone().multLocal(speed * tpf);
Vector3f camUp = cam.getUp().clone().mult(speed * tpf);
Quaternion roll = new Quaternion();
camDir.y = 0;
// ufoDirection2.set(0, 0, 0);
// ufoControl2.setLinearVelocity(Vector3f.ZERO);
if (doRoll == true) {
roll.fromAngleAxis(FastMath.QUARTER_PI / 3, cam.getDirection());
}
if (ufoControl2 == null) {
System.out.println("ufoControl2 == null");
}
ufoControl2.setPhysicsRotation(roll);
if (System.currentTimeMillis() - time > 1000) {
System.out.println("LOOP BREAK");
ufoDirection2.set(0, 0, 0);
ufoControl2.setLinearVelocity(Vector3f.ZERO);
time = 0;
player2update = false;
}
}
private boolean doRoll = false;
public boolean isDoRoll() {
return doRoll;
}
public void setDoRoll(boolean doRoll) {
this.doRoll = doRoll;
}
@Override
public void simpleUpdate(float tpf) {
playtime = System.currentTimeMillis() - starttime;
int speed = 25 * 80000;
Vector3f camDir = cam.getDirection().clone().multLocal(speed * tpf);
Vector3f camUp = cam.getUp().clone().mult(speed * tpf);
Quaternion roll = new Quaternion();
camDir.y = 0;
ufoDirection.set(0, 0, 0);
ufoControl.setLinearVelocity(Vector3f.ZERO);
if (left) {
roll.fromAngleAxis(-FastMath.QUARTER_PI / 3, cam.getDirection());
ufoDirection.set(cam.getLeft().multLocal(speed * tpf));
}
if (right) {
roll.fromAngleAxis(FastMath.QUARTER_PI / 3, cam.getDirection());
ufoDirection.set(cam.getLeft()).multLocal(-speed * tpf);
}
if (up) {
roll.fromAngleAxis(0, cam.getDirection());
ufoDirection.addLocal(camUp);
}
if (down) {
roll.fromAngleAxis(0, cam.getDirection());
ufoDirection.addLocal(cam.getUp().multLocal(-speed * tpf));
}
if (forward) {
roll.fromAngleAxis(0, cam.getDirection());
ufoDirection.set(camDir);
}
if (backward) {
roll.fromAngleAxis(0, cam.getDirection());
ufoDirection.set(camDir.multLocal(-1f));
}
ufoControl.setPhysicsRotation(roll);
ufoControl.setLinearVelocity(ufoDirection);
CollisionResults results = new CollisionResults();
System.out.println("1 #Collisions between" + ufoNode.getName()
+ " and " + jumpgateSpatial.getName() + ": " + results.size());
ufoNode.collideWith((BoundingBox) jumpgateSpatial.getWorldBound(),
results);
System.out.println("2 #Collisions between" + ufoNode.getName()
+ " and " + jumpgateSpatial.getName() + ": " + results.size());
CollisionResults results2 = new CollisionResults();
// Use the results
if (results.size() > 0 && playtime > 50000) {
System.out.println("playtime" + playtime);
System.out.println("#Collisions between" + ufoNode.getName()
+ " and " + jumpgateSpatial.getName() + ": "
+ results.size());
// how to react when a collision was detected
CollisionResult closest = results.getClosestCollision();
System.out.println("What was hit? "
+ closest.getGeometry().getName());
System.out
.println("Where was it hit? " + closest.getContactPoint());
System.out.println("Distance? " + closest.getDistance());
ufoControl
.setPhysicsLocation(jumpGateControl2.getPhysicsLocation());
System.out.println("Warped");
} else {
// how to react when no collision occured
}
if (results2.size() > 0) {
System.out.println("Number of Collisions between"
+ ufoNode.getName() + " and " + moon.getName() + ": "
+ results2.size());
// how to react when a collision was detected
CollisionResult closest2 = results2.getClosestCollision();
System.out.println("What was hit? "
+ closest2.getGeometry().getName());
System.out.println("Where was it hit? "
+ closest2.getContactPoint());
System.out.println("Distance? " + closest2.getDistance());
}
Message message = new ActionMessage(1, myClient.getId(), right);
if (myClient != null) {
myClient.send(message);
}
if (player2update == true) {
System.out.println("simpleUpdatePlayer2 player 2 "
+ message.toString());
time = System.currentTimeMillis();
simpleUpdatePlayer2(tpf);
}
}
boolean player2update = false;
public boolean isPlayer2update() {
return player2update;
}
public void setPlayer2update(boolean player2update) {
this.player2update = player2update;
}
}
答案 0 :(得分:3)
尽管在子类中实现了Serialization接口,但父级的字段不会被序列化。需要提供两种方法readObject
和writeObject
来处理父类的序列化过程(code)
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Vector3fSerializationExample {
static class Vector3f {
double x, y, z;
Vector3f() {
}
Vector3f(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
@Override
public String toString() {
return "Vector3f [x=" + x + ", y=" + y + ", z=" + z + "]";
}
}
static class Vector3fSubclass2 extends Vector3f implements Serializable {
private static final long serialVersionUID = 1L;
Vector3fSubclass2() {
}
Vector3fSubclass2(double x, double y, double z) {
super(x, y, z);
}
}
static class Vector3fSubclass extends Vector3f implements Serializable {
private static final long serialVersionUID = 1L;
Vector3fSubclass() {
}
Vector3fSubclass(double x, double y, double z) {
super(x, y, z);
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
x = ois.readDouble();
y = ois.readDouble();
z = ois.readDouble();
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeDouble(x);
oos.writeDouble(y);
oos.writeDouble(z);
}
}
static class SerializationUtil {
static Object deserialize(byte[] buff) throws IOException, ClassNotFoundException {
ByteArrayInputStream in = new ByteArrayInputStream(buff);
ObjectInputStream ois = new ObjectInputStream(in);
Object obj = ois.readObject();
ois.close();
return obj;
}
static byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(obj);
out.close();
return out.toByteArray();
}
}
public static void main(String[] args) throws Throwable {
Vector3f v3f = new Vector3fSubclass(1, 2, 3);
byte[] arr = SerializationUtil.serialize(v3f);
System.out.println(SerializationUtil.deserialize(arr));
v3f = new Vector3fSubclass2(1, 2, 3); //subclass without needed methods
arr = SerializationUtil.serialize(v3f);
System.out.println(SerializationUtil.deserialize(arr));
}
}
输出:
Vector3f [x=1.0, y=2.0, z=3.0]
Vector3f [x=0.0, y=0.0, z=0.0]
答案 1 :(得分:2)
如果Vector3f中的组件是可序列化的 你可以编写一个类,让它扩展Vector3f并让它实现Serializable。