【问题标题】:About Key Bindings in Java关于 Java 中的键绑定
【发布时间】:2014-01-04 16:08:00
【问题描述】:

这里的人们一直建议我在我的 Java 2D 游戏中使用 Key Bindings 而不是 Key Listener。

所以我学会了它,我想知道我是否正确理解如何使用它。

假设我有一个游戏,有两个游戏,每个玩家可以按下 5 个按钮。

玩家 1:

  • UP 箭头 - 向前移动
  • LEFT 箭头 - 改变移动角度
  • RIGHT 箭头 - 改变移动角度
  • SPACE 键 - 发射导弹
  • L 键 - 发射辅助导弹

玩家 2:

  • W 键 - 前进
  • A 键 - 改变移动角度
  • D 键 - 改变移动角度
  • CAPS-LOCK 键 - 发射导弹
  • “Z”键 - 发射辅助导弹

如果我希望程序对每个不同的按键做出不同的反应,那么我必须这样做:(?)

  1. 在内部创建 10 个扩展 AbstractAction 的新嵌套类 运行大部分游戏逻辑的类。
  2. 创建一个实例 这 10 个新类中的每一个,并将每个类绑定到一个键。

这是正确的吗?只为按下按钮创建 10 个新类真的合乎逻辑吗? 我想知道我是否正确理解如何使用 Key Bindings,以便我可以开始使用它进行编程。

谢谢

【问题讨论】:

    标签: java awt key-bindings


    【解决方案1】:

    “这是正确的吗?创建 10 个新类仅用于按下按钮真的合乎逻辑吗?”

    答案是肯定的。您确实需要创建 10 个不同的实例。这并不难。您可以创建一个帮助类,也可以复制和粘贴类似的内容

    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);  <----
    

    对于每个不同的操作,只需复制并粘贴Action 代码,更改变量和要执行的操作,然后相应地输入InputMapActionMap

    我将两种方式用于不同的场景。对于图形,我更喜欢上述方式。对于菜单之类的东西,我倾向于使用单独的类

    看看this example

    【讨论】:

    • 我知道我需要创建 10 个不同的实例。但是我需要创建 10 个不同的吗? (每个都有一个实例?)
    • 你在上面写的:它有什么作用?它是否创建了一个名为leftAction 的新类,扩展了AbstractAction?还是它会创建一个新的 AbstractAction 实例,然后为该特定实例覆盖 actionPerformed()?
    • 从技术上讲,使用上面的代码,您正在创建一个匿名类。对于不同的操作,您将不得不重复我的代码的顶部 10 次。
    • 这是一个匿名类。是的,leftAction 是类的变量。 AbstractAction 是一个需要覆盖 actionPerformed 的类,就像 ActionListener 类
    • 所以在第二条评论中回答我的问题:你上面写的等于'创建一个名为leftAction的新类,它扩展了AbstractAction'?或者它只是 AbstractAction 的另一个实例?
    【解决方案2】:
    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!");
            }
        }
    }
    

    取自here

    【解决方案3】:

    就个人而言,当我使用 keyBindings 时,我会为每个操作创建一个扩展 abstractAction 的内部类,然后创建这个内部类的一个实例并将其绑定到一个键,例如 put("left", ActionLeft);。所以基本上我做了你描述的两个步骤,并且有效。

    您也可以只创建匿名类的实例,然后以同样的方式绑定这些实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-15
      • 1970-01-01
      • 2013-02-23
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      相关资源
      最近更新 更多