简体   繁体   English

关于Java中的键绑定

[英]About Key Bindings in Java

People here keep suggesting to me to use Key Bindings in my Java 2D games instead of Key Listener. 这里的人们不断建议我在Java 2D游戏中使用“键绑定”,而不是“键侦听器”。

So I learned it and I'd like to know wether I understand correctly how to use it. 所以我学会了它,我想知道我是否正确地理解了如何使用它。

Let's say I have a game, with two playes, each player can push 5 buttons. 假设我有一个游戏,有两个游戏,每个玩家可以按5个按钮。

Player 1: 玩家1:

  • UP arrow - move forward 向上箭头-向前移动
  • LEFT arrow - change angle of movement 箭头-更改运动角度
  • RIGHT arrow - change angle of movement 向右箭头-更改运动角度
  • SPACE key - fire missile SPACE键-射击导弹
  • L key - fire secondary missile L键-火力辅助导弹

Player 2: 玩家2:

  • W key - move forward W键-前进
  • A key - change angle of movement 一个关键-改变运动角度
  • D key - change angle of movement D键-改变运动角度
  • CAPS-LOCK key - fire missile CAPS-LOCK键-射击导弹
  • 'Z' key - fire secondary missile Z键-射击辅助导弹

If I want the program to react differently to each one of the different key-presses, than this is what I have to do: (?) 如果我希望程序对每个不同的按键做出不同的反应,那么我要做的是:(?)

  1. Create 10 new nested classes extending AbstractAction, inside the class that runs most of the game logic. 在运行大多数游戏逻辑的类中,创建10个扩展AbstractAction的新嵌套类。
  2. Create an instance of every one of these 10 new classes, and bind each one to a key. 为这10个新类中的每一个创建一个实例,并将每一个绑定到一个键。

Is this correct? 这个对吗? Is it really logical to create 10 new classes only for pushing buttons? 仅为按钮创建10个新类真的合乎逻辑吗? I want to know if I understand correctly how to use Key Bindings, so I can start programming with it. 我想知道我是否正确理解如何使用键绑定,所以我可以开始使用它进行编程。

Thanks 谢谢

"Is this correct? Is it really logical to create 10 new classes only for pushing buttons?" “这是正确的吗?只为按钮创建10个新类真的合乎逻辑吗?”

The answer is YES. 答案是肯定的。 You do need to create 10 different instances. 您确实需要创建10个不同的实例。 It's not difficult. 不难 You can either create a helper class or you can just copy and paste something like this 您可以创建一个助手类,也可以复制和粘贴类似的内容

Action leftAction = new AbstractAction(){
    public void actionPerformed(ActionEvent e){
        // do something when left button pressed;
    }
};

InputMap inputMap = panel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = panel.getActionMap();

inputMap.put(KeyStroke.getKeyStroke("LEFT"), "leftAction");
actionMap.put("leftAction", leftAction);  <----

For each different action, just copy and paste the Action code, change the variable, and the action to perform, and input into the InputMap and the ActionMap accordingly. 对于每个不同的动作,只需复制并粘贴Action代码,更改变量以及要执行的动作,然后分别输入到InputMapActionMap

I use both ways for different scenarios. 我针对不同的情况使用两种方法。 For graphics i prefer the above way. 对于图形,我更喜欢上面的方式。 For things like menus, I tend to use a separate class 对于菜单之类的东西,我倾向于使用单独的类

Take a look at this example 这个例子

public TestKeyBindings02() {
    JPanel panel = new JPanel();
    InputMap im = panel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
    ActionMap am = panel.getActionMap();

    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "RightArrow");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "LeftArrow");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "UpArrow");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "DownArrow");

    am.put("RightArrow", new ArrowAction("RightArrow"));
    am.put("LeftArrow", new ArrowAction("LeftArrow"));
    am.put("UpArrow", new ArrowAction("UpArrow"));
    am.put("DownArrow", new ArrowAction("DownArrow"));
}

public class ArrowAction extends AbstractAction {

    private String cmd;

    public ArrowAction(String cmd) {
        this.cmd = cmd;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (cmd.equalsIgnoreCase("LeftArrow")) {
            System.out.println("The left arrow was pressed!");
        } else if (cmd.equalsIgnoreCase("RightArrow")) {
            System.out.println("The right arrow was pressed!");
        } else if (cmd.equalsIgnoreCase("UpArrow")) {
            System.out.println("The up arrow was pressed!");
        } else if (cmd.equalsIgnoreCase("DownArrow")) {
            System.out.println("The down arrow was pressed!");
        }
    }
}

Taken from here 这里取

Personaly, when I was using keyBindings I would create an inner class extending abstractAction for each action, then create an instance of this inner class and bind it to a key like put("left", ActionLeft); 个性而言,当我使用keyBindings时,我将创建一个内部类,为每个操作扩展abstractAction,然后创建该内部类的实例,并将其绑定到诸如put("left", ActionLeft);类的键上put("left", ActionLeft); , for example. , 例如。 So basically I did the two steps you've described and that worked. 因此,基本上,我完成了您描述的两个步骤,并且都成功了。

You could also just create instances of anonymus classes and then bind those instances just the same way. 您也可以只创建匿名类的实例,然后以相同的方式绑定这些实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM