In my quest to learn jME I discovered something odd in the way FirstPersonHandler sets keyboard actions. Here’s the current version of FirstPersonHandler for reference:
public class FirstPersonHandler extends InputHandler {
/**
* Creates a first person handler. The app is used for the exit action, camera
* is used for mouse look, and the api string is used to find the correct keyboard input.
* @param app The application that is exited on an "exit" action.
* @param cam The camera to move by this handler.
* @param api The API to create a KeyBindingManager from.
*/
public FirstPersonHandler(AbstractGame app, Camera cam, String api) {
setKeyBindings(cam);
setMouse(cam);
setActions(cam, app);
}
private void setKeyBindings(Camera cam) {
KeyBindingManager keyboard = KeyBindingManager.getKeyBindingManager();
InputSystem.createInputSystem(api);
keyboard.setKeyInput(InputSystem.getKeyInput());
keyboard.set("forward", KeyInput.KEY_W);
keyboard.set("backward", KeyInput.KEY_S);
keyboard.set("strafeLeft", KeyInput.KEY_A);
keyboard.set("strafeRight", KeyInput.KEY_D);
keyboard.set("lookUp", KeyInput.KEY_UP);
keyboard.set("lookDown", KeyInput.KEY_DOWN);
keyboard.set("turnRight", KeyInput.KEY_RIGHT);
keyboard.set("turnLeft", KeyInput.KEY_LEFT);
keyboard.set("screenshot", KeyInput.KEY_F12);
keyboard.set("exit", KeyInput.KEY_ESCAPE);
setKeyBindingManager(keyboard);
}
private void setMouse(Camera cam) {
RelativeMouse mouse = new RelativeMouse("Mouse Input");
mouse.setMouseInput(InputSystem.getMouseInput());
setMouse(mouse);
MouseLook mouseLook = new MouseLook(mouse, cam, 1.0f);
mouseLook.setKey("mouselook");
mouseLook.setLockAxis(new Vector3f(cam.getUp().x, cam.getUp().y, cam.getUp().z));
addAction(mouseLook);
}
private void setActions(Camera cam, AbstractGame app) {
KeyExitAction exit = new KeyExitAction(app);
exit.setKey("exit");
addAction(exit);
KeyScreenShotAction screen = new KeyScreenShotAction();
screen.setKey("screenshot");
addAction(screen);
KeyForwardAction forward = new KeyForwardAction(cam, 0.5f);
forward.setKey("forward");
addAction(forward);
KeyBackwardAction backward = new KeyBackwardAction(cam, 0.5f);
backward.setKey("backward");
addAction(backward);
KeyStrafeLeftAction strafeLeft = new KeyStrafeLeftAction(cam, 0.5f);
strafeLeft.setKey("strafeLeft");
addAction(strafeLeft);
KeyStrafeRightAction strafeRight = new KeyStrafeRightAction(cam, 0.5f);
strafeRight.setKey("strafeRight");
addAction(strafeRight);
KeyLookUpAction lookUp = new KeyLookUpAction(cam, 0.01f);
lookUp.setKey("lookUp");
addAction(lookUp);
KeyLookDownAction lookDown = new KeyLookDownAction(cam, 0.01f);
lookDown.setKey("lookDown");
addAction(lookDown);
KeyRotateRightAction rotateRight = new KeyRotateRightAction(cam, 0.01f);
rotateRight.setKey("turnRight");
addAction(rotateRight);
KeyRotateLeftAction rotateLeft = new KeyRotateLeftAction(cam, 0.01f);
rotateLeft.setKey("turnLeft");
addAction(rotateLeft);
}
}
While studying I noticed a method called addKeyboardAction() in InputHandler itself that wasn't being used and therefore creating a lot of duplicate code. Here's my version of FirstPersonHandler using that method:
public class FirstPersonHandler extends InputHandler {
/**
* Creates a first person handler. The app is used for the exit action, camera
* is used for mouse look, and the api string is used to find the correct keyboard input.
* @param app The application that is exited on an "exit" action.
* @param cam The camera to move by this handler.
* @param api The API to create a KeyBindingManager from.
*/
public FirstPersonHandler(AbstractGame app, Camera cam, String api) {
InputSystem.createInputSystem(api);
setKeyBindings(app, cam);
setMouse(cam);
}
private void setKeyBindings(AbstractGame app, Camera cam) {
addKeyboardAction("forward", KeyInput.KEY_W, new KeyForwardAction(cam, 0.5f));
addKeyboardAction("backward", KeyInput.KEY_S, new KeyBackwardAction(cam, 0.5f));
addKeyboardAction("strafeLeft", KeyInput.KEY_A, new KeyStrafeLeftAction(cam, 0.5f));
addKeyboardAction("strafeRight", KeyInput.KEY_D, new KeyStrafeRightAction(cam, 0.5f));
addKeyboardAction("lookUp", KeyInput.KEY_UP, new KeyLookUpAction(cam, 0.01f));
addKeyboardAction("lookDown", KeyInput.KEY_DOWN, new KeyLookDownAction(cam, 0.01f));
addKeyboardAction("turnRight", KeyInput.KEY_RIGHT, new KeyRotateRightAction(cam, 0.01f));
addKeyboardAction("turnLeft", KeyInput.KEY_LEFT, new KeyRotateLeftAction(cam, 0.01f));
addKeyboardAction("screenshot", KeyInput.KEY_F12, new KeyScreenShotAction());
addKeyboardAction("exit", KeyInput.KEY_ESCAPE, new KeyExitAction(app));
}
private void setMouse(Camera cam) {
RelativeMouse mouse = new RelativeMouse("Mouse Input");
mouse.setMouseInput(InputSystem.getMouseInput());
setMouse(mouse);
MouseLook mouseLook = new MouseLook(mouse, cam, 1.0f);
mouseLook.setKey("mouselook");
mouseLook.setLockAxis(new Vector3f(cam.getUp().x, cam.getUp().y, cam.getUp().z));
addAction(mouseLook);
}
}
This makes things a lot clearer for new users to understand, and also tells users that the method addKeyboardAction() exists to make their lives easier. What do you guys think?