I have been working on a control for player movement but I have not been able to get it to work. There are a couple of methods that I have attempted to control the player movement with but for some reason none of them are working in my control. At one point I had the rotation working a little, but it was not working quite right and I cant figure out what I changed that made it stop working.
Currently the player movement is controlled by the bullet app state which sets up correctly but does nothing after it drops the player into the scene.
This is most of the moveControl file which is supposed to manage all player movement. This file is instanced in simpleInitiateApp() as shown in the second code section. I only left out some set and get methods which are clearly described by their names.
[java]
public void registerWithInput(InputManager inputManager){
this.inputManager = inputManager;
inputManager.addMapping("Player_Left", new MouseAxisTrigger(MouseInput.AXIS_X, true),
new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("Player_Right", new MouseAxisTrigger(MouseInput.AXIS_X, false),
new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addMapping("Player_Up", new MouseAxisTrigger(MouseInput.AXIS_Y, false),
new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("Player_Down", new MouseAxisTrigger(MouseInput.AXIS_Y, true),
new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("Player_Forward", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("Player_Backward", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("Player_StrafeLeft", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("Player_StrafeRight", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this, mappings);
}
//method one:
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Player_StrafeLeft")) {
if (value) { left = true; } else { left = false; }
} else if (binding.equals("Player_StrafeRight")) {
if (value) { right = true; } else { right = false; }
} else if (binding.equals("Player_Forward")) {
if (value) { up = true; } else { up = false; }
} else if (binding.equals("Player_Backward")) {
if (value) { down = true; } else { down = false; }
} else if (binding.equals("Jump")) {
playerControl.jump();
}
playerDirection.set(Vector3f.ZERO.add(getDirection().x , 0, getDirection().z));
Vector3f playerLeft = getLeft().clone().multLocal(0.4f);
walkDirection.set(0, 0, 0);
if (left) { walkDirection.addLocal(playerLeft); }
if (right) { walkDirection.addLocal(playerLeft.negate()); }
if (up) { walkDirection.addLocal(playerDirection); }
if (down) { walkDirection.addLocal(playerDirection.negate()); }
playerControl.setWalkDirection(walkDirection);
spatial.setLocalTranslation(playerControl.getPhysicsLocation());
}
//method two:
public void onAnalog(String name, float value, float tpf) {
if (!moveEnabled) {
return;
}
if (name.equals("Player_Left")){
rotatePlayer(value, getUp());
}else if (name.equals("Player_Right")){
rotatePlayer(-value, getUp());
}else if (name.equals("Player_Up")){
rotatePlayer(-value, getLeft());
}else if (name.equals("Player_Down")){
rotatePlayer(value, getLeft());
}else if (name.equals("Player_Forward")){
movePlayer(value, false);
}else if (name.equals("Player_Backward")){
movePlayer(-value, false);
}else if (name.equals("Player_StrafeLeft")){
movePlayer(value, true);
}else if (name.equals("Player_StrafeRight")){
movePlayer(-value, true);
}
}
private void movePlayer(float value, boolean b) {
Vector3f vel = new Vector3f();
Vector3f pos = spatial.getLocalTranslation().clone();
sideways = b;
if (sideways){
getLeft(vel);
}else{
getDirection(vel);
}
vel.multLocal(value * moveSpeed);
walkDirection.addLocal(vel); //this line is unnecessary if walkDirection is not modified anywhere else.
playerControl.setWalkDirection(walkDirection);
spatial.setLocalTranslation(playerControl.getPhysicsLocation());
//this is a second possible way within this methodto handle movement but I would rather use the one above as I don't have to handle physics elsewhere.
pos.addLocal(vel);
setLocation(pos);
}
private void rotatePlayer(float value, Vector3f axis) {
Matrix3f mat = new Matrix3f();
mat.fromAngleNormalAxis(rotationSpeed * value, axis);
Vector3f up = getUp();
Vector3f left = getLeft();
Vector3f dir = getDirection();
mat.mult(up, up);
mat.mult(left, left);
mat.mult(dir, dir);
Quaternion q = new Quaternion();
q.fromAxes(left, up, dir);
q.normalizeLocal();
setAxes(q);
}
[/java]
Here are all of the parts of the simple initiate app that affect player movement:
[java]
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
playerControl = new CharacterControl(capsuleShape, 0.05f);
playerControl.setJumpSpeed(20);
playerControl.setFallSpeed(50);
playerControl.setGravity(40);
playerControl.setPhysicsLocation(new Vector3f(0, 10, 30));
//TODO: fix fall speed acceleration
bulletAppState.getPhysicsSpace().add(landscape);
bulletAppState.getPhysicsSpace().add(playerControl);
//Create the player node
playerNode = new PlayerNode();
moveControl = new PlayerMoveControl(bulletAppState, inputManager, playerControl);
playerNode.addControl(moveControl);
moveControl.setEnabled(true);
[/java]
I am probably missing something really simple but after hours of searching for the problem I just can't seem to find it.
Any help fixing this is greatly appreciated thanks.