Java Can';是否在循环中处理密钥绑定?

Java Can';是否在循环中处理密钥绑定?,java,swing,key-bindings,Java,Swing,Key Bindings,我正在尝试制作一个蛇游戏,一个普通的老式游戏,但是我在使用键绑定时遇到了一些困难 在我创建了Gui类的一个实例之后,它创建了JFrame、一个JPanel和一个JPanel数组。在这个例子之后,我喜欢使用while循环来检查玩家是否还活着,如果玩家还活着,蛇会根据难度每隔1/4秒移动一个方块 当不在while循环中时,我可以正确地使用keybinding,但当我让程序进入循环时,它无法使用按钮识别我 也许这是Java中的一个标准东西,我不知道。如果是,有人能告诉我应该如何处理我的问题吗 Inpu

我正在尝试制作一个蛇游戏,一个普通的老式游戏,但是我在使用键绑定时遇到了一些困难

在我创建了Gui类的一个实例之后,它创建了JFrame、一个JPanel和一个JPanel数组。在这个例子之后,我喜欢使用while循环来检查玩家是否还活着,如果玩家还活着,蛇会根据难度每隔1/4秒移动一个方块

当不在while循环中时,我可以正确地使用keybinding,但当我让程序进入循环时,它无法使用按钮识别我

也许这是Java中的一个标准东西,我不知道。如果是,有人能告诉我应该如何处理我的问题吗

InputMap im = base.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = base.getActionMap();

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "Right");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "Up");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "Down");

am.put("Right", new ArrowAction("Right"));
am.put("Left", new ArrowAction("Left"));
am.put("Up", new ArrowAction("Up"));
am.put("Down", new ArrowAction("Down"));
在课堂上:

public class ArrowAction extends AbstractAction {
    String txt;

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

    public void actionPerformed(ActionEvent e) {
        if (txt.equalsIgnoreCase("Left")) {
            System.out.println("The left arrow was pressed!");
            keyPressed = 0;
        } else if (txt.equalsIgnoreCase("Right")) {
            System.out.println("The right arrow was pressed!");
            keyPressed = 1;
        } else if (txt.equalsIgnoreCase("Up")) {
            System.out.println("The up arrow was pressed!");
            keyPressed = 2;
        } else if (txt.equalsIgnoreCase("Down")) {
            keyPressed = 3;
            System.out.println("The down arrow was pressed!");
        }
    }
}
和一般的while循环:

while (alive == true) {
   // Some stuff happening, not relevant
}

那么,为什么我的键绑定不在循环内工作,而在循环外工作呢?

您的问题在于“常规while循环”。这不是GUI应用程序的工作方式。在所有GUI应用程序(包括JavaSwing应用程序)中,框架运行循环并向您发送要响应的事件。您编写的所有内容都需要对事件做出响应。如果它是一个应该一直运行的后台任务,那么它需要在自己的线程上运行——但我怀疑你在游戏中是否需要它


因此,删除您的常规while循环,让“一些东西”在自己的线程中,或者(更有可能)在响应计时器时定期发生。

您可能需要使用线程应用程序,一个处理蛇的应用程序,一种是以这种方式处理播放器控件,两者同时运行。显然,事件处理代码与while循环位于同一线程上,因此当您在循环中执行某些操作时,应用程序无法处理新事件。while循环正在阻塞事件线程,这是一个很大的禁忌。与使用单独的线程来移动蛇相比,您应该订阅一个定期计时器,并在发生这种情况时更新蛇。我不习惯使用线程,因此我试图保持它的简单性,但我认为使用
Runnable
是一种更好的方法。下面给出了一个完整的示例。