Node controller

I've noticed their a couple of different ways to handle node movement so instead of making another class i guess i could use one of them however can anyone tell me which one to use for general movement in a tps i plan to use the same constructor for other movement elements ie ai, events. and one which only needs parameters for speed and the node it needs to be applied to so i can put it in another constructor so the initial parameters will be an animation and the node handler with the speed.



I've realized that their's several ways theirs a firstpersonhandler thirdpersonhandler and keynode can anone advise me on the differences???



also in the case of holding diagonal keys can anyone inform me of a proper way to implement it should i declare another if statement for the extra 4 directions or if i left it the other two declared values say left and up would work out fine even if i had two separate animations mapped to the buttons



Edit

I'm unsure if its worth mentioning but i set the camera slightly behind the target using a cameraNode

One of the key differences between a FirstPersonHandler and ThirdPersonHandler is the location of the camera. In the ThirdPersonHandler there's a ChaseCamera. This allows you to define how you want the camera to orbit around an entity in the game. Since you plan on making a tps (third person shooter?) I suggest using the ThirdPersonHandler. It's pretty easy to use.



For my game, which is a turn based rts which runs in a third person view, I use a ThirdPersonHandler with the player's avatar being the target of ChaseCamera. Each unit on the game map has it's own Controller for movement, which is my own special controller that extends from Controller. It seems to be working very well as all my units must live by the same rules of movement.



There's some great demos under jmetest that show how to write a custom Controller.



Hope this helps!

I ultimately want to be able to apply  KeyNodeStrafeLeftAction strafeLeft = new KeyNodeStrafeLeftAction(charNode, 15f);

        ac.addAction(strafeLeft, CubeAction.STRAFELEFT.name(), true);



instead of ETC…ETC

KeyNodeStrafeLeftAction strafeLeft = new KeyNodeStrafeLeftAction(charNode, 15f);

        ac.addAction(strafeLeft, CubeAction.STRAFELEFT.name(), true); ETC…ETC


Pandaemonium said:

One of the key differences between a FirstPersonHandler and ThirdPersonHandler is the location of the camera. In the ThirdPersonHandler there's a ChaseCamera. This allows you to define how you want the camera to orbit around an entity in the game. Since you plan on making a tps (third person shooter?) I suggest using the ThirdPersonHandler. It's pretty easy to use.

For my game, which is a turn based rts which runs in a third person view, I use a ThirdPersonHandler with the player's avatar being the target of ChaseCamera. Each unit on the game map has it's own Controller for movement, which is my own special controller that extends from Controller. It seems to be working very well as all my units must live by the same rules of movement.

There's some great demos under jmetest that show how to write a custom Controller.

Hope this helps!


so it would be best to use third person handler (i've attempted to initiate it before using the flasgrush tut but wtith little success) despite the fact that i had initially applied the camera node to be at a set distance behind the player?? I was looking firstperson handler again and it seems to be more appropriate however it seems as though it primarily controls the camera so if i applied a node to a root node and a camera to that node and the model node after that could that work or is it much easier to use ThirdPerson

also my current control system is this

package com.tps1.GameState;

import static com.jme.input.KeyInput.*;
import static com.jme.input.controls.binding.MouseButtonBinding.LEFT_BUTTON;
import static com.jme.input.controls.binding.MouseButtonBinding.RIGHT_BUTTON;
import static com.tps1.GameState.PlayerController.CubeAction.*;

import java.util.HashMap;


import com.jme.input.ChaseCamera;
import com.jme.input.FirstPersonHandler;
import com.jme.input.InputHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.ThirdPersonHandler;
import com.jme.input.action.KeyNodeBackwardAction;
import com.jme.input.action.KeyNodeForwardAction;
import com.jme.input.action.KeyNodeStrafeLeftAction;
import com.jme.input.action.KeyNodeStrafeRightAction;
import com.jme.input.controls.GameControl;
import com.jme.input.controls.GameControlManager;
import com.jme.input.controls.binding.KeyboardBinding;
import com.jme.input.controls.binding.MouseButtonBinding;
import com.jme.input.thirdperson.ThirdPersonMouseLook;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.scene.CameraNode;
import com.jme.scene.Controller;
import com.jme.scene.Node;
import com.jme.system.DisplaySystem;

public class PlayerController extends Controller{
   public enum CubeAction {STRAFELEFT, STRAFERIGHT, FORWARD, BACKWARD, EXIT};//Sets up actions as an enum   
   public static InputHandler ac = new InputHandler();//creates an input handler to handle input
   protected static GameControlManager manager;// = new GameControlManager();
   private final Node charNode;
   public PlayerController(Node charNode2){
      this.charNode = charNode2;
       manager = new GameControlManager();
       //create all actions
        for (CubeAction action : CubeAction.values()) {
            manager.addControl(action.name());
        }
        bindKey(EXIT, KEY_X);
         //bind keys for player 1       
          bindKey(FORWARD, KEY_I);
             bindKey(BACKWARD, KEY_K);
              bindKey(STRAFELEFT, KEY_J);
                bindKey(STRAFERIGHT, KEY_L);
       
 
        //bind mouse buttons
        bindMouseButton(STRAFELEFT, LEFT_BUTTON);
        bindMouseButton(STRAFERIGHT, RIGHT_BUTTON);
       
     
      
        /////Impliments Motion   
      KeyNodeForwardAction forward = new KeyNodeForwardAction(charNode, 105f);
       ac.addAction(forward, CubeAction.FORWARD.toString(), true);             
        KeyNodeBackwardAction backward = new KeyNodeBackwardAction(charNode, 15f);
        ac.addAction(backward, CubeAction.BACKWARD.toString(), true);       
        KeyNodeStrafeRightAction strafeRight = new KeyNodeStrafeRightAction(charNode, 150f);
        ac.addAction(strafeRight, CubeAction.STRAFERIGHT.name(), true);       
        KeyNodeStrafeLeftAction strafeLeft = new KeyNodeStrafeLeftAction(charNode, 15f);
        ac.addAction(strafeLeft, CubeAction.STRAFELEFT.name(), true);   //*/
       
       //initializes Camera
       setupCamera();
   }
   
   private void setupCamera() {
      // attach the CameraNode to the player node
      CameraNode camNode = new CameraNode("cam node", DisplaySystem.getDisplaySystem().getRenderer().getCamera());
      
      charNode.attachChild(camNode);
      // and move the camera a bit behind our player
      camNode.setLocalTranslation(-23, 0, -25);      
   }

   /**Binds the enum values to keys*/
    private void bindKey(CubeAction action, int... keys) {
        final GameControl control = manager.getControl(action.name());
        for (int key : keys) {
          control.addBinding(new KeyboardBinding(key));         
          KeyBindingManager.getKeyBindingManager().add(action.toString(), keys);           
                       }
                                              }
    /**Binds the enum values to mouse button*/
    private void bindMouseButton(CubeAction action, int mouseButton) {
        final GameControl control = manager.getControl(action.name());
        control.addBinding(new MouseButtonBinding(mouseButton));
    }
 /**returns specific enum value*/
    public static float value(CubeAction action) {
        return manager.getControl(action.name()).getValue();
    }

@Override
public void update(float time) {
   ac.update(time);//updates InputHandler 
}
   
}



would it be better if i was to use coredump's example

package com.jmedemos.examples.gamestates;

import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.controls.GameControl;
import com.jme.input.controls.GameControlManager;
import com.jme.input.controls.binding.KeyboardBinding;
import com.jme.input.controls.controller.ActionChangeController;
import com.jme.input.controls.controller.ControlChangeListener;
import com.jmex.game.state.BasicGameState;
import com.jmex.game.state.GameState;
import com.jmex.game.state.GameStateManager;

/**
 * Our InputGameState.
 * For comparison we use two different Input systems.
 *
 * To Enable/disable the TextGamestate (F1) we use the GamecontrolSystem.
 * For the other Keys, the easier to use KeyBindingManager is used.
 */
public class InputGameState extends BasicGameState {
    /**
     * constructor, creates the Inputhandler and actions to listen for.
     */
    public InputGameState(String name) {
        super(name);
       
        // the GameControl System:
        // 1. create GameControlManager, needed to create controls from
        GameControlManager manager = new GameControlManager();
        // 2. create a GameControl as input for the Controller later
        GameControl textTogglecontrol = manager.addControl("toggle_text");
        // 3. add a Key Binding to the gameControl (F1)
        textTogglecontrol.addBinding(new KeyboardBinding(KeyInput.KEY_F1));
        // 4. create a Controller, which gets the InputValues from the GameControl
        ActionChangeController textToggleAction = new ActionChangeController(textTogglecontrol, new ControlChangeListener() {
            public void changed(GameControl control, float oldValue,
                    float newValue, float time) {
                // toggle TextGameState active/inactive
                // get the GameState
                GameState textGS = GameStateManager.getInstance().getChild("text");
                // invert the GameStates active flag
                textGS.setActive(!textGS.isActive());
            }
        });
        // 5. add the controller to a node, so that it gets updated every update cycle.
        rootNode.addController(textToggleAction);
       
        // adding new actions to the KeybindingManager
        KeyBindingManager.getKeyBindingManager().add("toggle_3d", KeyInput.KEY_F2);
        KeyBindingManager.getKeyBindingManager().add("toggle_stat", KeyInput.KEY_F3);
        KeyBindingManager.getKeyBindingManager().set("exit", KeyInput.KEY_ESCAPE);
    }
   
    /**
     * Check if the a Key that we defined previously, has been pressed and execute the according action
     */
    public void update(float tpf) {
        super.update(tpf);
        // check if F2 has been pressed and toggle the 3D Gamestate
        if (KeyBindingManager.getKeyBindingManager().isValidCommand("toggle_3d", false)) {
            // invert the active flag of the 3D GameState
            GameStateManager.getInstance().getChild("3d").setActive(
                    !GameStateManager.getInstance().getChild("3d").isActive());
        }
       
        if (KeyBindingManager.getKeyBindingManager().isValidCommand("toggle_stat", false)) {
            // invert the active flag of the 3D GameState
            GameStateManager.getInstance().getChild("statistics").setActive(
                    !GameStateManager.getInstance().getChild("statistics").isActive());
        }
       
        // check if ESC has been pressed, exit the application if needed
        if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit", false)) {
            System.out.println("Good Bye");
            System.exit(0);
        }
    }
}



the ultimate goal is to create a constructor that looks like so

constructor(Animation,NodeController(movement Direction,speed))


so i guess an easy way to do it is to make several classes that continually moves the node so that i can control it by and if statement correct

Vector3f loc = node.getLocalTranslation();
loc.addLocal(node.getLocalRotation().getRotationColumn(2, tempVa)
.multLocal(speed * evt.getTime()));
node.setLocalTranslation(loc);
i could use this bit of code simply removing *evt.getTime() correct