My PlayerAppState is creating player node and attaching spatials to control. Exactly it is doing code:
public class PlayerAppState extends AbstractAppState implements ActionListener {
private PlayerData playerData;
private BulletAppState bulletAppState;
private Node rootNode;
private InputManager inputManager;
private AssetManager assetManager;
private boolean w, a, s, d;
private Node playerNode;
private Spatial player;
private BetterCharacterControl playerControl;
private Vector3f walkDirection = new Vector3f(0, 0, 0);
private Vector3f viewDirection = new Vector3f(0, 0, 0);
private Camera cam;
private CameraNode camNode;
public static final Quaternion PITCH045 = new Quaternion().fromAngleAxis(FastMath.PI/3/4, new Vector3f(1,0,0));
public PlayerAppState(BulletAppState bulletAppState, Node rootNode, PlayerData data) {
this.bulletAppState = bulletAppState;
this.rootNode = rootNode;
this.playerData = data;
}
@Override
public void initialize(AppStateManager stateManager, Application app) {
super.initialize(stateManager, app); //To change body of generated methods, choose Tools | Templates.
this.inputManager = app.getInputManager();
this.assetManager = app.getAssetManager();
this.cam = app.getCamera();
initPlayer();
initInput();
}
private void initInput() {
inputManager.addMapping("UP", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("DOWN", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("LEFT", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("RIGHT", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("JUMP", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("RESET", new KeyTrigger(KeyInput.KEY_RETURN));
inputManager.addListener(this, new String[] {"UP", "DOWN", "LEFT", "RIGHT", "JUMP", "RESET"});
}
private void initPlayer() {
playerNode = new Node();
player = assetManager.loadModel("Models/player/player.j3o");
player.setLocalTranslation(0, 0, 0);
playerControl = new BetterCharacterControl(.45f, 1.8f, 80);
playerNode.addControl(playerControl);
playerControl.setGravity(new Vector3f(0, 20, 0));
playerControl.setJumpForce(new Vector3f(0, 320, 0));
playerControl.warp(new Vector3f(0, 2, 0));
playerNode.attachChild(player);
camNode = new CameraNode("CamNode", cam);
playerNode.attachChild(camNode);
camNode.setLocalTranslation(new Vector3f(0, 3f, -5));
camNode.setLocalRotation(PITCH045);
bulletAppState.getPhysicsSpace().addAll(playerNode);
rootNode.attachChild(playerNode);
}
@Override
public void update(float tpf) {
Vector3f camDir = cam.getDirection().mult(0.2f);
Vector3f camLeft = cam.getLeft().mult(0.003f);
camDir.y = 0;
camLeft.y = 0;
viewDirection.set(camDir);
walkDirection.set(Vector3f.ZERO);
if (w) {
walkDirection.addLocal(cam.getDirection());
}
if (a) {
viewDirection.addLocal(camLeft);
}
if (s) {
walkDirection.addLocal(cam.getDirection().negate());
}
if (d) {
viewDirection.addLocal(camLeft.negate());
}
walkDirection.setY(0);
playerControl.setWalkDirection(walkDirection.multLocal(5));
playerControl.setViewDirection(viewDirection.multLocal(0.5f));
refreshPlayerData();
}
private void refreshPlayerData() {
playerData.setLocation(playerNode.getLocalTranslation());
playerData.setRotation(playerNode.getLocalRotation());
playerData.setWalkDirection(playerControl.getWalkDirection());
playerData.setViewDirection(playerControl.getViewDirection());
}
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("UP")) {
w = isPressed;
}
if (name.equals("DOWN")) {
s = isPressed;
}
if (name.equals("LEFT")) {
a = isPressed;
}
if (name.equals("RIGHT")) {
d = isPressed;
}
if (name.equals("JUMP")) {
playerControl.jump();
}
if (name.equals("RESET")) {
playerControl.warp(new Vector3f(0, 0, 0));
}
}
}
but ClientMain is calling PlayerAppState after creating client with id for server. And creating scene too. For precision posting ClientMain code:
public class ClientMain extends SimpleApplication implements ClientStateListener {
private Client client;
private PlayerAppState playerAppState;
private BulletAppState bulletAppState;
private PlayerData playerData;
private SceneManager sceneManager;
public static void main(String[] args) {
Utils.initSerializers();
ClientMain app = new ClientMain();
app.setPauseOnLostFocus(false);
app.start();
}
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(true);
flyCam.setMoveSpeed(30);
flyCam.setDragToRotate(true);
sceneManager = new SceneManager(this, assetManager, bulletAppState);
initPlayerData();
initConnection();
initAppStates();
initScene();
}
@Override
public void simpleUpdate(float tpf) {
if (client.isConnected()) {
client.send(new PlayerDataMessage(playerData));
}
}
private void initConnection() {
try {
client = Network.connectToServer(Utils.IP_ADRESS, Utils.PORT);
client.addMessageListener(new ClientListener(client, sceneManager));
client.addClientStateListener(this);
client.start();
System.out.println("Client erfolgreich connected!");
} catch (IOException ex) {
Logger.getLogger(ClientMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void clientConnected(Client c) {
playerData.setId(c.getId());
sceneManager.setMyID(c.getId());
client.send(new TextMessage("Hello Server! I'm ID: " + c.getId()));
System.out.println("C: " + c);
System.out.println("PD: " + playerData);
}
public void clientDisconnected(Client c, DisconnectInfo info) {
}
private void initAppStates() {
playerAppState = new PlayerAppState(bulletAppState, rootNode, playerData);
stateManager.attach(playerAppState);
}
private void initScene() {
Material cityMat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
cityMat.setTexture("DiffuseMap", assetManager.loadTexture("Materials/cityTex1.png"));
Box floor = new Box(50, 0, 50);
Geometry floorGeom = new Geometry("City", floor);
floorGeom.setMaterial(cityMat);
floorGeom.setLocalTranslation(new Vector3f(0, 0, 0));
floorGeom.addControl(new RigidBodyControl(new MeshCollisionShape(floorGeom.getMesh()), 0));
rootNode.attachChild(floorGeom);
bulletAppState.getPhysicsSpace().add(floorGeom);
/**
* A white ambient light source.
*/
AmbientLight ambient = new AmbientLight();
ambient.setColor(ColorRGBA.White);
rootNode.addLight(ambient);
/**
* A white, directional light source
*/
DirectionalLight sun = new DirectionalLight();
sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal());
sun.setColor(ColorRGBA.White);
rootNode.addLight(sun);
}
private void initPlayerData() {
playerData = new PlayerData();
}
@Override
public void destroy() {
bulletAppState.cleanup();
// ...
client.send(new CloseConnectionMessage(playerData.getId()));
super.destroy();
}
But at first, I want only to make car that will be visible for every player on the scene and players be able to push the car and see how it moves.
I have searched for some tutorials but each is so different from other and I do not know which I should use. If anyone found a good tutorial, I will try code it by that tutor.
Thank you so much.