【问题标题】:Handling two keypresses in java在java中处理两个按键
【发布时间】:2014-08-27 20:24:57
【问题描述】:

我的代码有问题,因为我不知道当你同时按下 ARROW UP 和 ARROW LEFT 等时如何让图片对角移动。这是我的代码:

 public void keyPressed(KeyEvent ke) {
    switch (ke.getKeyCode()) {
    case KeyEvent.VK_RIGHT: {
        cordX += 5;
    }
        break;
    case KeyEvent.VK_LEFT: {
        cordX -= 5;
    }
        break;
    case KeyEvent.VK_DOWN: {
        cordY += 5;
    }
        break;
    case KeyEvent.VK_UP: {
        cordY -= 3;
    }
        break;
    }
    repaint();
}

我不知道这是否可行

case KeyEvent.VK_UP  &&  KeyEvent.VK_LEFT: {
        cordY += 5;
    }
        break;

【问题讨论】:

  • 首先拿到你的break;内箱。

标签: java keypress


【解决方案1】:

如果您使用 Swing 组件,请使用 Key Bindings API,请参阅How to Use Key Bindings,它将解决很多问题...

无论如何,解决方案(基本上)是相同的,您需要做的是定义一系列标志,这些标志定义当前按下了哪些键,并定期更新受这些标志影响的变量的状态

private boolean down, up, left, right;
//...

public void keyPressed(KeyEvent ke) {
    switch (ke.getKeyCode()) {
        case KeyEvent.VK_RIGHT:
            right = true;
            break;
        case KeyEvent.VK_LEFT:
            left = true;
            break;
        case KeyEvent.VK_DOWN:
            down = true;
            break;
        case KeyEvent.VK_UP:
            up = true;
            break;
    }
    updateState();
}

public void keyReleased(KeyEvent ke) {
    switch (ke.getKeyCode()) {
        case KeyEvent.VK_RIGHT:
            right = false;
            break;
        case KeyEvent.VK_LEFT:
            left = false;
            break;
        case KeyEvent.VK_DOWN:
            down = false;
            break;
        case KeyEvent.VK_UP:
            up = false;
            break;
    }
    updateState();
}

protected void updateState() {
    if (right) {
        cordX += 5;
    } else if (left) {
        cordX -= 5;
    }
    if (down) {
        cordY += 5;
    } else if (up) {
        cordY -= 3;
    }
    repaint();
}

然后您可以使用javax.swing.Timer 安排定期回调,该回调可用于调用updateState(而不是从键事件处理程序中调用它)。

查看How to use Swing Timers了解更多详情...

【讨论】:

  • 不,我想让我的程序知道当你按下两个键时它必须是对角线。
  • 是的,所以当一个键被按下时,它会将相应的标志设置为true。因此,如果您按下“向上”和“向左”键,upleft 标志将为 true,当您释放一个键时,该标志将重置为 false。然后,您可以使用javax.swing.Timer 之类的东西定期触发回调以调用(类似于)updateState(来自我的示例),这将根据标志的状态更新 x/y 值...一直这样做,就像这样,很有效
  • 这是一个基于 example 的 Swing/Key 绑定,但使用相同的原理...
  • @Jollyfreak 谢谢(编辑),我以为我已经这样做了:P
【解决方案2】:

您可以使用Timer

public class MyClass extends KeyAdapter implements ActionListener {

    private Timer timer; //this timer will update your object's position
    private int vx = 0; //these values indicate your objects velocity
    private int vy = 0; //they are updated as your arrow keys are pressed

    public MyClass() {
        this.timer = new Timer(100 /*the delay*/, this/*the listener*/);
        //the delay indicated how frequently you want to update your position, i chose 100ms, you may chose a different number
    }

    @Override public void keyPressed(KeyEvent ke) {
        switch (ke.getKeyCode()) {
            case KeyEvent.VK_RIGHT:
                vx = 5;
            break;
            case KeyEvent.VK_LEFT:
                vx = -5;
            break;
            case KeyEvent.VK_DOWN:
                vy = 5;
            break;
            case KeyEvent.VK_UP:
                vy = -3;
            break;
        }
        this.timer.start(); //start your timer when a key is pressed (will do nothing if it's already running)
    }

    //obviously, you will need to stop your objects once the keys are released.
    @Override public void keyReleased(KeyEvent ke) {
        switch(ke.getKeyCode()) {
            case KeyEvent.VK_RIGHT:
                vx = 0;
            break;
            case KeyEvent.VK_LEFT:
                vx = 0;
            break;
            case KeyEvent.VK_DOWN:
                vy = 0;
            break;
            case KeyEvent.VK_UP:
                vy = 0;
            break;
        }
        if(vx == 0 && vy == 0) this.timer.stop(); //no need to run the timer if no key is down
    }

    //this will be called regularly by the timer
    @Override public void actionPerformed(ActionEvent ae) {
        cordX += vx; //you just update the positions
        cordY += vy; //according to your variables
        repaint(); //then repaint
    }
}

编辑:您可以对此进行优化以避免(例如)同时按下左右键时出现奇怪的行为。

【讨论】:

  • 这是个人的事情。我宁愿简单地提供一个简单的“标志”来确定给定“动作”的状态,以便您可以将输入与数据分开,但这只是我;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-27
相关资源
最近更新 更多