【翻译】JMonkeyEngine——Input Handling

输入处理

用户通过鼠标、键盘或者手柄等输入设备与jME3应用程序进行交互。我们使用SimpleApplication中的inputManager来响应用户输入。

下面是给游戏添加交互的步骤:

  1. 给每个action选择一个或多个触发器(trigger),例如键盘、鼠标点击等;
  2. 给每个action添加一个从trigger到inputManager间的映射;
  3. 在SimpleApplication中创建至少一个监听;
  4. 将每个action的映射(步骤2中提到的)注册给监听器;
  5. 在监听中实现每个action的具体内容。

代码样例

TestControls.java

    @Override
    public void simpleInitApp() {
        // 1.选择触发器:空格和鼠标滑轮
        // 2.建立映射
        inputManager.addMapping("My Action",
                new KeyTrigger(KeyInput.KEY_SPACE),
                new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false));

        // 3.创建监听
        // 4.给监听注册mappings
        inputManager.addListener(actionListener, "My Action");
        inputManager.addListener(analogListener, "My Action");
    }
    // 5.在监听中实现action
    private ActionListener actionListener = new ActionListener(){
        public void onAction(String name, boolean pressed, float tpf){
            System.out.println(name + " = " + pressed);
        }
    };
    public AnalogListener analogListener = new AnalogListener() {
        public void onAnalog(String name, float value, float tpf) {
            System.out.println(name + " = " + value);
        }
    };

TestJoystick.java

1.选择触发器(Trigger)

为交互选择一个或多个触发事件。我们使用com.jme3.input.controls包中的KeyTrigger,MouseAxisTrigger,MouseButtonTrigger,JoyAxisTrigger和JoyButtonTrigger。

MouseAxis和JoyAxis沿着x轴(左/右)和y轴(上/下)。这两个触发器多了一个布尔型参数,false代表负半轴,即左和下。记得在监听时写上正半轴和负半轴。

【翻译】JMonkeyEngine——Input Handling_第1张图片
MouseTriggers.png
【翻译】JMonkeyEngine——Input Handling_第2张图片
KeyboardTriggers.png
【翻译】JMonkeyEngine——Input Handling_第3张图片
JoystickTriggers.png

2.删除默认触发器映射

inputManager.deleteMapping( SimpleApplication.INPUT_MAPPING_MEMORY );
【翻译】JMonkeyEngine——Input Handling_第4张图片
默认映射

3.添加自定义触发器

在初始化应用的时候,给每个触发器添加一个映射。

给映射一个有意义的名字。这个名字需要能反映出action本身,而不是所按的按键,比如:

inputManager.addMapping("Pause Game", new KeyTrigger(KeyInput.KEY_P));
inputManager.addMapping("Rotate",     new KeyTrigger(KeyInput.KEY_SPACE));
...

下面的例子介绍了如何给一个action添加多个触发器。例如,有的用户喜欢用wasd键控制方向,而有的则喜欢用方向键。用逗号分开每个触发器:

inputManager.addMapping("Left",  new KeyTrigger(KeyInput.KEY_A),
                                 new KeyTrigger(KeyInput.KEY_LEFT)); // A and left arrow
inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D),
                                 new KeyTrigger(KeyInput.KEY_RIGHT)); // D and right arrow
                                 ...

4. 创建监听

jME3提供两种输入监听:AnalogListener和ActionListener。同一个应用中你可以使用一个也可以两个都使用.

这两个输入监听不知道也不在乎那个键被点击,他们只知道被出发的映射的名称(named input mapping)。

ActionListener

  • 用于监听确切的“按键点击或松开”动作。
    • 例如:暂停/开始,用步枪或左轮枪涉及,跳,点击选择。
  • jME3可以访问的是:
    • 触发动作的名称
    • 代表是否仍在点击或已经松开的布尔值
    • 当前每帧时间的浮点数
private ActionListener actionListener = new ActionListener() {
  public void onAction(String name, boolean keyPressed, float tpf) {
     /** TODO: test for mapping names and implement actions */
  }
};

AnalogListener

  • 用于持续动作
    • 例如:走路、跑、旋转、加速车辆、扫射、半自动武器射击
  • jME3可以访问的是:
    • 触发动作的名称
    • 代表是否仍在点击或已经松开的布尔值
    • 当前每帧时间的浮点数
private AnalogListener analogListener = new AnalogListener() {
  public void onAnalog(String name, float keyPressed, float tpf) {
     /** TODO: test for mapping names and implement actions */
  }
};

5.给监听注册映射

要想激活映射,必须将其注册给监听。在添加mappings到inputManager的代码块后面注册监听。

在下面的例子中,将把“Pause Game”注册给actionListener对象。

inputManager.addListener(actionListener, new String[]{"Pause Game"});

在下面的例子中,将把方向mappings注册给analogLisioner对象,因为走路时持续的过程,用户需要一直按着按键。

inputManager.addListener(analogListener, new String[]{"Left", "Right"});

如你所见,可以用数组的方式将多个动作加到一个监听里。这样可以让代码整洁。

6. 实现监听

将具体的action写到监听的TODO中。最典型的,写一系列if/else条件语句,判断映射名称,然后调用相应的action。
注意if和else if的区别。

  • 如果一些action可以被同时触发,则使用一系列“if”。例如,一个角色可以向前跑也可以同时向左跑。
  • 如果action间相互排斥,则使用else if,这样其他的就会被跳过。比如射击和捡东西,只能同时满足一个。

ActionListener

一般来讲,你希望一个action只在按下按键或松开按键是被触发一次。比如,点某个键后开门,或者捡起一个东西。这些情况下,使用ActionListener,并且加一个&&!keyPressed语句,如下。

private ActionListener actionListener = new ActionListener() {
    public void onAction(String name, boolean keyPressed, float tpf) {

      if (name.equals("Pause Game") && !keyPressed) { // test?
        isRunning = !isRunning;                       // action!
      }

      if ...

    }
  };

AnalogListener

下面的例子展示了如何用AnalogListener定义action。这些动作被持续触发,只要按键或鼠标被点击。该监听可以被用于半自动武器射击和方向导航。

private AnalogListener analogListener = new AnalogListener() {
    public void onAnalog(String name, float value, float tpf) {

      if (name.equals("Rotate")) {         // test?
        player.rotate(0, value*speed, 0);  // action!
      }

      if ...

    }
  };

用户自定义key map

很有可能你的用户使用不同的键盘布局,或者“鼠标反向”,或者喜欢不同于你设定的方向键来控制方向。这时就该设置一个“设置界面”,让用户自定义触发的按键。用变量替代inputManager.addMapping()中的内容,然后在游戏开始时加载这些设置。

分离triggers和mappings的好处在于可以很简单地remap。你的代码只需要删除并添加一些触发器映射,代码核心不变。

你可能感兴趣的:(【翻译】JMonkeyEngine——Input Handling)