【翻译】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代表负半轴,即左和下。记得在监听时写上正半轴和负半轴。

MouseTriggers.png
KeyboardTriggers.png
JoystickTriggers.png

2.删除默认触发器映射

inputManager.deleteMapping( SimpleApplication.INPUT_MAPPING_MEMORY );
默认映射

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。你的代码只需要删除并添加一些触发器映射,代码核心不变。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,264评论 19 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 47,224评论 6 342
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 177,065评论 25 709
  • 偷偷看动物园,女儿看了这个就睡觉了,今天又把长颈鹿家的门撕坏了,我要哭了!
    依荷妈妈绘本阅读大V店阅读 1,409评论 0 0
  • 产品名称:多看阅读 v4.5.6 业务描述:电子书(出版图书、网络小说、漫画)购买和阅读工具。 核心场景: ...
    撒疯的点阅读 1,562评论 0 0

友情链接更多精彩内容