Hi All,
I have migrated FlagRush to FPS (with other Player model + Node). I have changed:
FlagRushTestServer - changed Vehicle to Player object
FlagRushTestClient - changed Vehicle to Player object
FlagRushTest - changed Vehicle to Player and change buildRemotePlayer
When running server and client,they got connected but player is not replicated on client side I got:
Unable to find object: 1 on Client
another strange message on client is:
WARNING: message is not a playermessage: com.captiveimagination.jgn.synchronizat
ion.message.SynchronizeRequestIDMessage@8c2f76
I try some debugging in JGN and checked that on client side,message doesn't contain player(or are empty)
here is my code:
changes in Server&Client are cosmetic, so only Player and FlagRushTest:
Player
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import com.captiveimagination.jgn.synchronization.SyncObjectManager;
import com.captiveimagination.jgn.synchronization.message.SynchronizeCreateMessage;
import com.captiveimagination.jgn.synchronization.message.SynchronizeRemoveMessage;
import com.captiveimagination.jmenet.flagrush.fps.Player;
import com.jme.bounding.BoundingCapsule;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.util.GameTaskQueueManager;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.MilkToJme;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import jmetest.intersection.TestPick;
public abstract class FlagRushTest implements SyncObjectManager {
private Node scene;
public void setScene(Node scene) {
this.scene = scene;
}
public Object create(SynchronizeCreateMessage scm) {
System.out.println("CREATING PLAYER!");
return buildRemotePlayer();
}
public boolean remove(SynchronizeRemoveMessage srm, Object obj) {
return removeRemotePlayer((Player)obj);
}
private Player buildRemotePlayer() {
Future<Player> future = GameTaskQueueManager.getManager().update(new Callable<Player> () {
public Player call() throws Exception {
Spatial model = null;
MilkToJme converter = new MilkToJme();
URL MSFile = TestPick.class.getClassLoader().getResource(
"jmetest/data/model/msascii/run.ms3d");
ByteArrayOutputStream BO = new ByteArrayOutputStream();
try {
converter.convert(MSFile.openStream(), BO);
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
model = null;
try {
model = (Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO
.toByteArray()));
model.setModelBound(new BoundingCapsule());
model.updateModelBound();
} catch (IOException e) {
e.printStackTrace();
}
//((JointController) model.getController(0)).setActive(false);
//model.setLocalScale(.002f);
Player player = new Player();
player.setModel(model);
player.setLocalTranslation(new Vector3f(100,0, 100));
scene.attachChild(player);
scene.updateGeometricState(0, true);
player.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
scene.updateRenderState();
return player;
}
});
try {
return future.get();
} catch(Exception exc) {
exc.printStackTrace();
}
return null;
}
private boolean removeRemotePlayer(Player player) {
return player.removeFromParent();
}
}
Player:
import java.util.Random;
import com.jme.animation.SpatialTransformer;
import com.jme.bounding.BoundingCapsule;
import com.jme.input.InputHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.CameraNode;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.system.DisplaySystem;
import com.jme.util.Timer;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.MilkToJme;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import jmetest.intersection.TestPick;
/**
*
* @author vlad
*/
public class Player extends Node{
private static int i = 1;
private static float maxHealth = 3000;
public static int playerBulletGroundHitSamples = 3;
private static int playerDeadEvent = 2;
private static int playerHitEvent = 1;
private static Random r = new Random();
/**
* @return Returns the maxHealth.
*/
public static float getMaxHealth()
{
return maxHealth;
}
/**
* @param maxHealth
* The maxHealth to set.
*/
public static void setMaxHealth(float maxHealth)
{
Player.maxHealth = maxHealth;
}
private int attachedWeapon;
/**
* has our camera and our gun
*/
private CameraNode camNode;
private float currentHealth;
/**
* our bullet action
*/
private FireBullet fireBullet;
/**
* has our laser gun
*/
private Node gunLaser;
/**
* has our MP5 gun
*/
private Node gunMP5;
private float hitPlayTime = 0.2f;
/**
* is player alive ?!
*/
private boolean isAlive;
private boolean isHit;
/**
* handles all keyboard commands
*/
private KeyBindingManager keyboard;
private Quaternion origRot = new Quaternion();
public int[] playerBulletEventsArray;
public int[] playerBulletSamplesArray;
public int playerBulletSoundNode;
private int playerDeadSample;
/**
* amount of bullets the player was hit
*/
private int playerHits = 0;
private int playerHitSample;
private int playerSoundNode;
private Quaternion rot = new Quaternion();
private Node target;
private Spatial model;
/**
* mouse input
*/
private MouseInput thisMouse;
private MySpatialTransformer trans = new MySpatialTransformer(1);
/**
* creates a new Player and attaches a gun to the camNode
*
* @param camNode
* @param input
* @param target
* @param timer
*/
public Player(CameraNode camNode, InputHandler input, Node target,
Timer timer)
{
super("Player");
this.camNode = camNode;
this.target = target;
currentHealth = maxHealth;
initGuns();
// set controls
setControlBindings("LWJGL", input, timer);
isHit = false;
isAlive = true;
buildPlayerModel();
}
public Player(){
super("Player");
currentHealth = maxHealth;
//buildPlayerModel();
//initGunsRemote();
// set controls
isHit = false;
isAlive = true;
}
/**
* change to the specified gun
*
* @param type
*/
public void changeGun(int type)
{
camNode.detachAllChildren();
if (type == WeaponMachineGun.MP5)
{
camNode.attachChild(gunMP5);
attachedWeapon = WeaponMachineGun.MP5;
fireBullet.setAttachedWeapon(attachedWeapon);
}
if (type == WeaponLaser.LASER)
{
camNode.attachChild(gunLaser);
attachedWeapon = WeaponLaser.LASER;
fireBullet.setAttachedWeapon(attachedWeapon);
}
camNode.updateGeometricState(0.0f, true);
camNode.updateRenderState();
}
/**
* check if a specified key is pressed or any specified mouse action occured
* and performs the specified action should be called every frame in
* simpleUpdate
*/
public void checkInput()
{
if (isAlive)
{
if (keyboard.isValidCommand("changeToLaser", true))
{
changeGun(WeaponLaser.LASER);
}
if (keyboard.isValidCommand("changeToMP5", true))
{
changeGun(WeaponMachineGun.MP5);
}
if (keyboard.isValidCommand("altFire", true))
{
fireBullet.setAltFire(true);
fireBullet.setThirdFire(false);
fireBullet.performAction(null);
}
if (keyboard.isValidCommand("fire", true))
{
fireBullet.setAltFire(false);
fireBullet.setThirdFire(false);
fireBullet.performAction(null);
}
if (keyboard.isValidCommand("thirdFire", true))
{
fireBullet.setAltFire(false);
fireBullet.setThirdFire(true);
fireBullet.performAction(null);
}
int test = thisMouse.getWheelDelta();
if (test < 0 || test > 0)
{
if (attachedWeapon == WeaponMachineGun.MP5)
{
changeGun(WeaponLaser.LASER);
}
else if (attachedWeapon == WeaponLaser.LASER)
{
changeGun(WeaponMachineGun.MP5);
}
}
if (thisMouse.isButtonDown(0))
{
fireBullet.setAltFire(false);
fireBullet.setThirdFire(false);
fireBullet.performAction(null);
}
// second fire mode
if (thisMouse.isButtonDown(1))
{
fireBullet.setAltFire(true);
fireBullet.setThirdFire(false);
fireBullet.performAction(null);
}
// third fire mode
if (thisMouse.isButtonDown(2))
{
fireBullet.setAltFire(false);
fireBullet.setThirdFire(true);
fireBullet.performAction(null);
}
}
if (keyboard.isValidCommand("takeScreenShot", false))
{
DisplaySystem.getDisplaySystem().getRenderer().takeScreenShot("screenshots/screen" + i);
i++;
}
}
/**
* should be called when the player died
*/
public void die()
{
isAlive = false;
// last cry here ;D
Vector3f pos = camNode.getWorldTranslation();
}
public int getAttachedWeapon()
{
return attachedWeapon;
}
/**
* @return Returns the currentHealth.
*/
public float getCurrentHealth()
{
return currentHealth;
}
/**
* @return Returns the currentHealth.
*/
public float getCurrentHealthInPercent()
{
return (currentHealth / maxHealth) * 100;
}
/**
* @return Returns the hitPlayTime.
*/
public float getHitPlayTime()
{
return hitPlayTime;
}
/**
* @return Returns the playerHits.
*/
public int getPlayerHits()
{
return playerHits;
}
/**
* gets a random sample identifier of the specified sample identifier amount
*
* @param amountOfSamples
* @return
*/
public int getRandomSample(int amountOfSamples)
{
return r.nextInt(amountOfSamples);
}
/**
* load a new gun at startup
*/
private void initGuns()
{
gunMP5 = WeaponMachineGun.createMP5();
gunMP5.setName("MP5Node");
gunLaser = WeaponLaser.createLaser();
gunLaser.setName("LaserNode");
attachedWeapon = WeaponLaser.LASER;
// reset cam
camNode.getCamera().setLocation(new Vector3f(0, 0, 0));
camNode.setLocalTranslation(new Vector3f(0, 0, 0));
// attach first Weapon
camNode.attachChild(gunLaser);
}
private void initGunsRemote()
{
gunMP5 = WeaponMachineGun.createMP5();
gunMP5.setName("MP5Node");
gunLaser = WeaponLaser.createLaser();
gunLaser.setName("LaserNode");
attachedWeapon = WeaponLaser.LASER;
// reset cam
//model.attachChild(gunLaser);
}
/**
* @return Returns the isAlive.
*/
public boolean isAlive()
{
return isAlive;
}
/**
* @return Returns the isHit.
*/
public boolean isHit()
{
return isHit;
}
/**
* should be called when the player is hit
*/
public void playerHit()
{
playerHits++;
// play a blood particle effect ;O
/*ParticleMesh manager = ExplosionFactory.getHitEffect();
manager.setLocalScale(0.65f);
manager.setLocalTranslation(new Vector3f(camNode.getLocalTranslation()));
manager.forceRespawn();
camNode.getParent().attachChild(manager);
manager.setCullHint(Spatial.CullHint.Never);*/
//manager.setForceView(true);
// cry here ;D
Vector3f pos = camNode.getWorldTranslation();
playHitAnimation();
}
/**
* shakes the camera ;D
*/
private void playHitAnimation()
{
// is player is hit again although the animation hasn't fully played
trans.setActive(false);
camNode.removeController(trans);
camNode.setLocalRotation(origRot);
// only use this if you don'T use removeController();
origRot = camNode.getWorldRotation();
trans = new MySpatialTransformer(1);
// origRot = camNode.getWorldRotation();
trans.setObject(camNode, 0, -1);
// rot up-down
rot.fromAngleAxis(FastMath.DEG_TO_RAD * (r.nextInt(20) - 10),
new Vector3f(1, 0, 0));
trans.setRotation(0, 0, origRot.mult(rot));
// rot left-right
rot.fromAngleAxis(FastMath.DEG_TO_RAD * (r.nextInt(20) - 10),
new Vector3f(0, 1, 0));
trans.setRotation(0, hitPlayTime / 2, origRot.mult(rot));
// set back to orig rotation
trans.setRotation(0, hitPlayTime, origRot);
trans.interpolateMissing();
trans.setRepeatType(SpatialTransformer.RT_CLAMP);
camNode.addController(trans);
isHit = true;
}
/**
* remove all controls
* @param input
*/
public void removeControlBindings(InputHandler input)
{
keyboard.remove("changeToLaser");
keyboard.remove("changeToMP5");
keyboard.remove("fire");
keyboard.remove("altFire");
keyboard.remove("thirdFire");
// keyboard.remove("cheatOn");
// keyboard.remove("cheatOff");
input.removeAction(fireBullet);
// clears all
// input.clearKeyboardActions();
// input.clearMouseActions();
}
/**
* removes the controller when from the hit animation
*/
public void removeController()
{
trans.setActive(false);
camNode.removeController(trans);
// should be set new here only cause the isHit method could be called
// again
// although the animation is not over yet...here it is over
// and the controller can also be removed...
origRot = camNode.getWorldRotation();
}
/**
* @param isAlive
* The isAlive to set.
*/
public void setAlive(boolean isAlive)
{
this.isAlive = isAlive;
}
/**
* set all control bindings
*/
private void setControlBindings(String api, InputHandler input, Timer timer)
{
keyboard = KeyBindingManager.getKeyBindingManager();
// InputSystem.createInputSystem(api);
keyboard.set("changeToLaser", KeyInput.KEY_1);
keyboard.set("changeToMP5", KeyInput.KEY_2);
keyboard.set("fire", KeyInput.KEY_F);
keyboard.set("altFire", KeyInput.KEY_R);
keyboard.set("thirdFire", KeyInput.KEY_G);
keyboard.set("takeScreenShot", KeyInput.KEY_F9);
/**
* Set the action called "firebullet", bound to KEY_Space, to
* performAction FireBullet
*/
fireBullet = new FireBullet(camNode, timer, target);
input.addAction(fireBullet,"firebullet",true);
// set mouse input
thisMouse = MouseInput.get();
}
/**
* @param currentHealth
* The currentHealth to set.
*/
public void setCurrentHealth(float currentHealth)
{
this.currentHealth = currentHealth;
}
/**
* @param isHit
* The isHit to set.
*/
public void setHit(boolean isHit)
{
this.isHit = isHit;
}
private void buildPlayerModel(){
MilkToJme converter = new MilkToJme();
URL MSFile = TestPick.class.getClassLoader().getResource(
"jmetest/data/model/msascii/run.ms3d");
ByteArrayOutputStream BO = new ByteArrayOutputStream();
try {
converter.convert(MSFile.openStream(), BO);
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
model = null;
try {
model = (Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO
.toByteArray()));
model.setModelBound(new BoundingCapsule());
model.updateModelBound();
} catch (IOException e) {
e.printStackTrace();
}
//((JointController) model.getController(0)).setActive(false);
//camNode.attachChild(model);
}
public void setModel(Spatial model){
this.model = model;
}
}