gpt4 book ai didi

java - 对于多人游戏场景,如何在客户端之间序列化更新消息?

转载 作者:可可西里 更新时间:2023-11-01 02:44:54 25 4
gpt4 key购买 nike

对于 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 移动时的方向 vector 。我的 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;
}
}

最佳答案

尽管在子类中实现了序列化接口(interface),但父类的字段不会被序列化。需要提供readObjectwriteObject两个方法来处理父类的序列化过程(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]

关于java - 对于多人游戏场景,如何在客户端之间序列化更新消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24222385/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com