- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
对于 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),但父类的字段不会被序列化。需要提供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]
关于java - 对于多人游戏场景,如何在客户端之间序列化更新消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24222385/
我需要修复 getLineNumberFor 方法,以便如果 lastName 的第一个字符位于 A 和 M 之间,则返回 1;如果它位于 N 和 Z 之间,则返回 2。 在我看来听起来很简单,但我不
您好,感谢您的帮助!我有这个: 0 我必须在每次点击后增加“pinli
Javascript 中是否有一种方法可以在不使用 if 语句的情况下通过 switch case 结构将一个整数与另一个整数进行比较? 例如。 switch(integer) { case
我有一列是“日期”类型的。如何在自定义选项中使用“之间”选项? 最佳答案 请注意,您有2个盒子。 between(在SQL中)包含所有内容,因此将框1设置为:DATE >= startdate,将框2
我有一个表,其中包含年、月和一些数字列 Year Month Total 2011 10 100 2011 11 150 2011 12 100 20
这个问题已经有答案了: Extract a substring between double quotes with regular expression in Java (2 个回答) how to
我有一个带有类别的边栏。正如你在这里看到的:http://kees.een-site-bouwen.nl/ url 中类别的 ID。带有 uri 段(3)当您单击其中一个类别时,例如网页设计。显示了一
这个问题在这里已经有了答案: My regex is matching too much. How do I make it stop? [duplicate] (5 个答案) 关闭 4 年前。 我
我很不会写正则表达式。 我正在尝试获取括号“()”之间的值。像下面这样的东西...... $a = "POLYGON((1 1,2 2,3 3,1 1))"; preg_match_all("/\((
我必须添加一个叠加层 (ImageView),以便它稍微移动到包含布局的左边界的左侧。 执行此操作的最佳方法是什么? 尝试了一些简单的方法,比如将 ImageView 放在布局中并使用负边距 andr
Rx 中是否有一些扩展方法来完成下面的场景? 我有一个开始泵送的值(绿色圆圈)和其他停止泵送的值(簧片圆圈),蓝色圆圈应该是预期值,我不希望这个命令被取消并重新创建(即“TakeUntil”和“Ski
我有一个看起来像这样的数据框(Dataframe X): id number found 1 5225 NA 2 2222 NA 3 3121 NA 我有另一个看起来
所以,我正在尝试制作正则表达式,它将解析存储在对象中的所有全局函数声明,例如,像这样 const a = () => {} 我做了这样的事情: /(?:const|let|var)\s*([A-z0-
我正在尝试从 Intellivision 重新创建 Astro-Smash,我想让桶保持在两个 Angular 之间。我只是想不出在哪里以及如何让这个东西停留在两者之间。 我已经以各种方式交换了函数,
到处检查但找不到答案。 我有这个页面,我使用 INNER JOIN 将两个表连接在一起,获取它们的值并显示它们。我有这个表格,用来获取变量(例如开始日期、结束日期和卡号),这些变量将作为从表中调用值的
我陷入了两个不同的问题/错误之间,无法想出一个合适的解决方案。任何帮助将不胜感激 上下文、FFI 和调用大量 C 函数,并将 C 类型包装在 rust 结构中。 第一个问题是ICE: this pat
我在 MySQL 中有一个用户列表,在订阅时,时间戳是使用 CURRENT_TIMESTAMP 在数据库中设置的。 现在我想从此表中选择订阅日期介于第 X 天和第 Y 天之间的表我尝试了几个查询,但不
我的输入是开始日期和结束日期。我想检查它是在 12 月 1 日到 3 月 31 日之间。(年份可以更改,并且只有在此期间内或之外的日期)。 到目前为止,我还没有找到任何关于 Joda-time 的解决
我正在努力了解线程与 CPU 使用率的关系。有很多关于线程与多处理的讨论(一个很好的概述是 this answer )所以我决定通过在运行 Windows 10、Python 3.4 的 8 CPU
我正在尝试编写 PHP 代码来循环遍历数组以创建 HTML 表格。我一直在尝试做类似的事情: fetchAll(PDO::FETCH_ASSOC); ?>
我是一名优秀的程序员,十分优秀!