Hey,
I tried to develop a jme multiplaygame, where the advanced vehicle is synchronized.
(same as discussed in http://www.jmonkeyengine.com/jmeforum/index.php?topic=7490.msg63657#msg63657)
Here the controller code:
package vig.game.network.controller;
import vig.game.scene.VehicleNode;
import vig.game.scene.vehicles.TutorialCar;
import com.captiveimagination.jgn.synchronization.GraphicalController;
import com.captiveimagination.jgn.synchronization.message.SynchronizeCreateMessage;
import com.captiveimagination.jgn.synchronization.message.SynchronizeMessage;
import com.captiveimagination.jgn.synchronization.message.SynchronizeRemoveMessage;
import com.jme.math.Vector3f;
/**
* This is a basic implementation of the GraphicalControler for the jME-Physics project.
*
* @author Matthew D. Hicks
*/
public class CarController implements GraphicalController<VehicleNode> {
private Vector3f store;
public CarController() {
store = new Vector3f();
}
public void applySynchronizationMessage(SynchronizeMessage message, VehicleNode car) {
System.out.print('.');
CarMessage m = (CarMessage) message;
m.applayToCar(car);
}
public SynchronizeMessage createSynchronizationMessage(VehicleNode car) {
CarMessage message = new CarMessage();
message.setCar(car);
return message;
}
/**
* This method will always return 1.0f. It is recommended to override this method in games to provide better efficiency to synchronization.
*/
public float proximity(VehicleNode dpn, short playerId) {
return 1.0f;
}
/**
* This method will always return true. It is recommended to override this method in games to provide a layer of security.
*/
public boolean validateMessage(SynchronizeMessage message, VehicleNode dpn) {
return true;
}
public boolean validateCreate(SynchronizeCreateMessage message) {
return true;
}
public boolean validateRemove(SynchronizeRemoveMessage message) {
return true;
}
}
but when i try it i get the following exception....
com.captiveimagination.jgn.convert.ConversionException: Error during Java deserialization.
at com.captiveimagination.jgn.convert.SerializableConverter.readObjectData(SerializableConverter.java:57)
at com.captiveimagination.jgn.convert.Converter.readClassAndObject(Converter.java:185)
at com.captiveimagination.jgn.convert.FieldConverter.readObjectData(FieldConverter.java:108)
at com.captiveimagination.jgn.convert.Converter.readClassAndObject(Converter.java:185)
at com.captiveimagination.jgn.NIOMessageServer.readMessage(NIOMessageServer.java:190)
at com.captiveimagination.jgn.UDPMessageServer.read(UDPMessageServer.java:116)
at com.captiveimagination.jgn.NIOMessageServer.updateTraffic(NIOMessageServer.java:143)
at com.captiveimagination.jgn.clientserver.JGNServer.updateTraffic(JGNServer.java:172)
at com.captiveimagination.jgn.clientserver.JGNServer.update(JGNServer.java:160)
at com.captiveimagination.jgn.UpdatableRunnable.run(JGN.java:435)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.io.UTFDataFormatException
at java.io.ObjectInputStream$BlockDataInputStream.readUTFSpan(ObjectInputStream.java:3082)
at java.io.ObjectInputStream$BlockDataInputStream.readUTFBody(ObjectInputStream.java:3007)
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(ObjectInputStream.java:2820)
at java.io.ObjectInputStream.readUTF(ObjectInputStream.java:1051)
at java.io.ObjectStreamClass.readNonProxy(ObjectStreamClass.java:616)
at java.io.ObjectInputStream.readClassDescriptor(ObjectInputStream.java:809)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1565)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at com.captiveimagination.jgn.convert.SerializableConverter.readObjectData(SerializableConverter.java:55)
... 10 more
what might be the reason????
Here the code of our vehicle, which is build out of the tutorial car:
package vig.game.scene;
import vig.game.hud.BulletInterface;
import vig.game.hud.HudNode;
import vig.game.hud.LifeInterface;
import vig.game.scene.vehicles.DummyVehicle;
import vig.game.scene.vehicles.TutorialCar;
import vig.game.scene.vehicles.VehicleModel;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jmex.physics.PhysicsSpace;
public class VehicleNode extends Node {
private static final long serialVersionUID = 4785222707809565983L;
final static public int DUMMY = 0;
final static public int TUTORIALCAR = 1;
int maxEnergy = 1;
int currEnergy = 1;
protected int collisionTolerance = 500;
protected int currToleranceLevel = collisionTolerance;
int weaponS = 0;
int weaponM = 0;
int weaponL = 0;
int enginePower;
VehicleModel model;
int modelType = 0;
int playerNumber;
boolean hudLinked = false;
HudNode hud;
int portalImmunityCounter = 0;
public VehicleNode(PhysicsSpace pSpace, int modelType, int maxEnergy, int playerNumber)
{
this(modelType,maxEnergy,playerNumber);
this.setModel(modelType, pSpace);
}
public VehicleNode(int modelType, int maxEnergy, int playerNumber)
{
this.maxEnergy = maxEnergy;
this.currEnergy = maxEnergy;
this.playerNumber = playerNumber;
this.modelType = modelType;
initVehicle();
}
public void build(PhysicsSpace pSpace)
{
setModel(modelType, pSpace);
}
protected void initVehicle()
{
setName("Vehicle" + playerNumber);
setRenderQueueMode(Renderer.QUEUE_OPAQUE);
}
/**
* Loads the model with the given ID to this.
*
* @param modelID
* @param pSpace
*/
public void setModel(int modelID, PhysicsSpace pSpace)
{
switch (modelID)
{
case TUTORIALCAR:
model = new TutorialCar(pSpace, enginePower, this);
break;
default:
model = new DummyVehicle(pSpace, enginePower, this);
};
attachChild(model);
updateGeometricState(0.0f, true);
updateRenderState();
}
/**
* Reduces the energy by the given amount.
*
* @param amount
*/
public void reduceEnergy(int amount)
{
currEnergy = currEnergy - amount;
if (this.hudLinked)
{
((LifeInterface)this.hud.getInterface(HudNode.LIFE_INTERFACE)).setValue(this.currEnergy);
}
}
/**
* Increases the current energy by the given amount.
* <br />
* If the sum of current energy and given amount would be higher
* than the maximum of energy, the vehicle can store, the current
* energy will only be set to the maximum.
*
* @param amount
*/
public void increaseEnergy(int amount)
{
if (currEnergy + amount < maxEnergy)
{
currEnergy = currEnergy + amount;
}
else
{
currEnergy = maxEnergy;
}
if (this.hudLinked)
{
((LifeInterface)this.hud.getInterface(HudNode.LIFE_INTERFACE)).setValue(this.currEnergy);
}
}
/**
* Returns the number of energy points, the vehicle currently has.
*
* @return
*/
public int getEnergy()
{
return currEnergy;
}
/**
* Returns the maximum of energy, this verhicle can store.
*
* @return
*/
public int getMaxEnergy()
{
return maxEnergy;
}
/**
* Returns the player's number.
*
* @return
*/
public int getPlayerNumber()
{
return playerNumber;
}
/**
* Returns the model representing this vehicle.
*
* @return
*/
public VehicleModel getModel()
{
return model;
}
/**
* Returns the number of bullets of the given type available
* for this vehicle.
*
* @param weaponType Weapon's type from WeaponNode
* @return int Number of bullets for the given weapon type
*/
public int getBulletQuantity(int weaponType)
{
switch (weaponType)
{
case WeaponNode.SIZES:
return weaponS;
case WeaponNode.SIZEM:
return weaponM;
case WeaponNode.SIZEL:
return weaponL;
default:
return 0;
}
}
/**
* Increases the number of bullets of the given type by
* the given number of bullets.
*
* @param weaponType Type of the weapon whose bullet number is increased
* @param number Number of bullets to add to the existing bullets
*/
public void increaseBulletQuantity(int weaponType, int number)
{
switch (weaponType)
{
case WeaponNode.SIZES:
weaponS = weaponS + number;
if (this.hudLinked)
{
((BulletInterface)this.hud.getInterface(HudNode.BULLET_INTERFACE)).setText(WeaponNode.SIZES,String.valueOf(weaponS));
}
break;
case WeaponNode.SIZEM:
weaponM = weaponM + number;
if (this.hudLinked)
{
((BulletInterface)this.hud.getInterface(HudNode.BULLET_INTERFACE)).setText(WeaponNode.SIZEM,String.valueOf(weaponM));
}
break;
case WeaponNode.SIZEL:
weaponL = weaponL + number;
if (this.hudLinked)
{
((BulletInterface)this.hud.getInterface(HudNode.BULLET_INTERFACE)).setText(WeaponNode.SIZEL,String.valueOf(weaponL));
}
break;
}
}
/**
* Decreases the number of bullets of the given type by
* the given number of bullets.
*
* @param weaponType Type of the weapon whose bullet number is decresed
* @param number Number of bullets to remove from the existing bullets
*/
public void decreaseBulletQuantity(int weaponType, int number)
{
switch (weaponType)
{
case WeaponNode.SIZES:
weaponS = (weaponS - number > 0) ? weaponS - number : 0;
if (this.hudLinked)
{
((BulletInterface)this.hud.getInterface(HudNode.BULLET_INTERFACE)).setText(WeaponNode.SIZES,String.valueOf(weaponS));
}
break;
case WeaponNode.SIZEM:
weaponM = (weaponM - number > 0) ? weaponM - number : 0;
if (this.hudLinked)
{
((BulletInterface)this.hud.getInterface(HudNode.BULLET_INTERFACE)).setText(WeaponNode.SIZEM,String.valueOf(weaponM));
}
break;
case WeaponNode.SIZEL:
weaponL = (weaponL - number > 0) ? weaponL - number : 0;
if (this.hudLinked)
{
((BulletInterface)this.hud.getInterface(HudNode.BULLET_INTERFACE)).setText(WeaponNode.SIZEL,String.valueOf(weaponL));
}
break;
}
}
/**
* Returns the tolerance of this vehicle against collisions.
* <br />
* The higher the value, the less damage will be done by collisions.
*
* @return
*/
public int getCollisionTolerance()
{
return collisionTolerance;
}
/**
* Sets the tolerance of this vehicle against collisions.
* <br />
* The higher the value, the less damage will be done by collisions.
*
* @param toleranceValue
*/
public void setCollisionTolerance(int toleranceValue)
{
if (toleranceValue > 0)
{
collisionTolerance = toleranceValue;
}
}
/**
* Sets the current tolerance level.
* <br />
* Every time when a collision event is fired on the vehicle, the
* tolerance level should be decreased. If it reaches 0, the vehicle
* will take damage. The tolerance level should be reset after this.
* Its highest value is defined by the collision tolerance of this vehicle.
*
* @param toleranceLevel
*/
public void setToleranceLevel(int toleranceLevel)
{
if (toleranceLevel > 0 && toleranceLevel <= this.collisionTolerance)
{
this.currToleranceLevel = toleranceLevel;
}
else if (toleranceLevel > this.collisionTolerance)
{
this.currToleranceLevel = this.collisionTolerance;
}
}
/**
* Resets the current tolerance level to the value
* of the collision tolerance.
* <br />
* Every time when a collision event is fired on the vehicle, the
* tolerance level should be decreased. If it reaches 0, the vehicle
* will take damage. The tolerance level should be reset after this.
* Its highest value is defined by the collision tolerance of this vehicle.
*
*/
public void resetToleranceLevel()
{
this.currToleranceLevel = this.collisionTolerance;
}
/**
* Reduces the current tolerance level by the given value.
* <br />
* Every time when a collision event is fired on the vehicle, the
* tolerance level should be decreased. If it reaches 0, the vehicle
* will take damage. The tolerance level should be reset after this.
* Its highest value is defined by the collision tolerance of this vehicle.
*
* @param value
*/
public void reduceToleranceLevel(int value)
{
if (this.currToleranceLevel - value < 0)
{
this.currToleranceLevel = 0;
}
else
{
this.currToleranceLevel = this.currToleranceLevel - value;
}
}
/**
* Returns the value of the current tolerance level.
* <br />
* Every time when a collision event is fired on the vehicle, the
* tolerance level should be decreased. If it reaches 0, the vehicle
* will take damage. The tolerance level should be reset after this.
* Its highest value is defined by the collision tolerance of this vehicle.
* @return
*/
public int getToleranceLevel()
{
return currToleranceLevel;
}
/**
* Links a HudNode to data of this vehicle.
*
* @param hud
*/
public void linkHud(HudNode hud)
{
if (hud != null)
{
this.hudLinked = true;
this.hud = hud;
((LifeInterface)this.hud.getInterface(HudNode.LIFE_INTERFACE)).setMaxValue(this.maxEnergy);
((LifeInterface)this.hud.getInterface(HudNode.LIFE_INTERFACE)).setValue(this.currEnergy);
}
}
/**
* Removes the HudNode currently linked to this vehicle.
*/
public void unlinkHud()
{
if (this.hudLinked)
{
this.hudLinked = false;
this.hud = null;
}
}
/**
* Returns the HudNode currently linked to this vehicle.
*
* @return
*/
public HudNode getHud()
{
return this.hud;
}
/**
* Returns true, if this vehicle was linked to a HudNode, else false.
*
* @return
*/
public boolean isLinkedToHud()
{
return this.hudLinked;
}
public void makePortalImmune()
{
this.portalImmunityCounter = 250;
}
public void decreasePortalImmunityCounter()
{
if (this.portalImmunityCounter > 0)
{
this.portalImmunityCounter--;
}
}
public boolean isPortalImmune()
{
return (this.portalImmunityCounter > 0);
}
}