KeyListener随机停止工作。键绑定?

时间:2016-11-01 22:26:07

标签: java swing awt keylistener key-bindings

我正在使用RealTutsGML的教程制作游戏,所以如果你看过他的一些旧的2013年视频,你会看到这段代码的大纲来自哪里。

(顺便说一下,我不是Java的新手,但我对AWT和Swing相当新,因为我曾经/有时会编写Minecraft Bukkit / Spigot插件。我能理解一个体面的Java常规语言/语法的数量,但AWT和Swing ...)

无论如何,我使用KeyAdapter来控制键。但是,它首先工作,然后随机停止工作。我调试了它,它似乎不是游戏中的对象,它是KeyAdapter。我已经找到了其他一些解决方案,人们已经说它失去了焦点或其他东西,我应该使用KeyBindings代替。这很奇怪,因为KeyListener RANDOMLY停止为我工作。

无论如何,这是我正在使用的代码:

Handler handler;

public KeyInput(Handler handler){
    this.handler = handler;

}



public void keyPressed(KeyEvent e){
    int key = e.getKeyCode();

    for (int i = 0; i < handler.object.size(); i++){
        GameObject tempObject = handler.object.get(i);

        if (tempObject.getId() == ObjectId.Player){
            if (key == KeyEvent.VK_SPACE && !tempObject.isJumping()){
                tempObject.setJumping(true);
                tempObject.setVelY(-10);
            }

            if (key == KeyEvent.VK_Y){
                tempObject.setY(100);
            }

            if (key == KeyEvent.VK_A){
                System.out.println("Pressed A");
                tempObject.setVelX(-5);
            }
            if (key == KeyEvent.VK_D){
                System.out.println("Pressed D");

                tempObject.setVelX(5);
            }

        }
    }

}
public void keyReleased(KeyEvent e) {

    int key = e.getKeyCode();

    for (int i = 0; i < handler.object.size(); i++) {

        GameObject tempObject = handler.object.get(i);

        if (tempObject.getId() == ObjectId.Player) {



            if (key == KeyEvent.VK_D) {
                for (int velX = (int) tempObject.getVelX(); velX >= 0; velX--) {
                    tempObject.setVelX(velX);
                }
            }
            if (key == KeyEvent.VK_A) {
                for (int velX = (int) tempObject.getVelX(); velX <= 0; velX++) {
                    tempObject.setVelX(velX);
                }
            }
        }
    }
}

正如您所看到的,我正在使用KeyAdapter来执行此操作。这是我在主类中的初始化方法:

private void init(){
    WIDTH = getWidth();
    HEIGHT = getHeight();
    handler = new Handler();
    handler.addObject(new Player(100, 100, handler, ObjectId.Player));
    handler.createTestLevel();

    this.addKeyListener(new KeyInput(handler));

}

在&#34; this.requestFocusInWindow()&#34;

之前调用init方法

我查了一些关于此的信息,我看到KeyBindings是解决其他人问题的方法。但是,我认为你必须为JComponents添加键绑定,而且我不知道如何在游戏中获得其中一个。新的JComponent()不起作用,我的JFrame正在添加我的主类(我相信它是一个组件,而不是JComponent)。

如果有人可以提供帮助,那就太棒了!谢谢!

编辑#1:

我切换到KeyBindings!这是KeyInput类:

Handler handler;

public JComponent component;

public KeyInput(Handler handler, JComponent component){
    this.handler = handler;
    this.component = component;

    register();
}

public void register(){
    Actions actions = new Actions();

    component.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressSpace");
    component.getActionMap().put("pressSpace", actions.pressSpace());

    component.getInputMap().put(KeyStroke.getKeyStroke("A"), "pressLeft");
    component.getActionMap().put("pressLeft", actions.pressLeft());
    component.getInputMap().put(KeyStroke.getKeyStroke("released A"), "releaseLeft");
    component.getActionMap().put("releaseLeft", actions.releaseXMovement());

    component.getInputMap().put(KeyStroke.getKeyStroke("D"), "pressRight");
    component.getActionMap().put("pressRight", actions.pressRight());
    component.getInputMap().put(KeyStroke.getKeyStroke("released D"), "releaseRight");
    component.getActionMap().put("releaseRight", actions.releaseXMovement());
}

public JComponent finish(){
    return component;
}


public class Actions{

    public Actions() { }

    public Action pressRight(){
        Action action = new AbstractAction(){
            private static final long serialVersionUID = 1L;

            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < handler.object.size(); i++){
                    GameObject temp = handler.object.get(i);
                    if (temp.getId() == ObjectId.Player){
                        temp.setVelX(5);
                        System.out.println("pressed right debug");
                    }
                }
            }

        };
        return action;
    }

    public Action releaseXMovement(){
        Action action = new AbstractAction(){
            private static final long serialVersionUID = 1L;

            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < handler.object.size(); i++){
                    GameObject temp = handler.object.get(i);
                    if (temp.getId() == ObjectId.Player){
                        temp.setVelX(0);
                    }
                }
            }

        };
        return action;
    }
    public Action pressLeft(){
        Action action = new AbstractAction(){
            private static final long serialVersionUID = 1L;

            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < handler.object.size(); i++){
                    GameObject temp = handler.object.get(i);
                    if (temp.getId() == ObjectId.Player){
                        temp.setVelX(-5);
                    }
                }
            }

        };
        return action;
    }

    public Action pressSpace(){
        Action action = new AbstractAction(){
            private static final long serialVersionUID = 1L;

            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < handler.object.size(); i++){
                    GameObject temp = handler.object.get(i);
                    if (temp.getId() == ObjectId.Player){
                        if (!temp.isJumping()){
                            temp.setJumping(true);
                            temp.setVelY(-10);
                        }
                    }
                }
            }

        };
        return action;
    }

}

然而,我仍然有同样的冻结问题。调试消息不会被发送,这意味着它与我的setVel方法没有任何关系。我不知道为什么听众会停止工作...... (它最初起作用,但是当我按下键时,它最终会停止)。

以下是我如何获得JComponent:

JComponent comp = (JComponent) frame.getContentPane();
    KeyInput input = new KeyInput(handler, comp);
    frame.add(input.finish());

1 个答案:

答案 0 :(得分:1)

它没有&#34;随机&#34;停止工作。相反,当听取的组件不再具有焦点时,它可能(我们无法在没有您的有效MCVE的情况下确定)停止工作。选择是创建一个kludge来强制关注组件(坏)或使用键绑定(好)。

关于:

  

我查了一些关于此的信息,我看到KeyBindings是解决其他人问题的方法。但是,我认为你必须为JComponents添加键绑定,而且我不知道如何在游戏中获得其中一个。新的JComponent()不起作用,我的JFrame正在添加我的主类(我相信它是一个组件,而不是JComponent)。

您的GUI充满了JComponents,从JFrame的contentPane开始,然后继续使用您要编程的任何其他GUI组件 - 请记住,大多数所有 Swing组件都会扩展来自JComponent,这些是添加绑定的有效组件。您可能会将其添加到GUI的主要JPanel或JComponent中。