【问题标题】:AWT KeyListener slow reactionAWT KeyListener 反应慢
【发布时间】:2012-06-09 19:03:52
【问题描述】:

我正在使用 Java Swing 创建一个简单的游戏。我有一个问题 - KeyListener 的反应似乎有点不稳定/缓慢。角色使用以下代码移动:

// player control
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        switch(key){
        case(KeyEvent.VK_LEFT): dx = -speed; break;
        case(KeyEvent.VK_RIGHT): dx = speed; break;
        case(KeyEvent.VK_UP): dy = -speed; break;
        case(KeyEvent.VK_DOWN): dy = speed; break;
        }
    }

public void keyReleased(KeyEvent e) {
    int key = e.getKeyCode();
    switch(key){
    case(KeyEvent.VK_LEFT): dx = 0; break;
    case(KeyEvent.VK_RIGHT): dx = 0; break;
    case(KeyEvent.VK_UP): dy = 0; break;
    case(KeyEvent.VK_DOWN): dy = 0; break;
    }
}

// this method is performed each time before redrawing the screen
public void step() {
    x += dx;
    y += dy;
}

大多数时候一切都很好,但有时角色会在对键盘做出反应之前停止一段时间。如何让键盘输入更流畅?

【问题讨论】:

  • 可能是“键重复速度”。您是否考虑过使用键绑定?
  • 这根本不是真的,反应慢???,肯定有一个问题==取决于你的代码......(同样将使用KeyBinding),对于使用SSCCE 更好地帮助您尽快编辑您的问题
  • 实际上在阅读了有关键绑定的信息后,它们的工作方式似乎与KeyListener 相同,我还想知道是否可以在 KeyPressed 事件被触发后“退出”它,所以它不会重复
  • 从键盘到KeyListener的正确输出与KeyBindings相同,但相似之处已经结束,接下来的一切都是关于FocusFocusSubsystemKeyBindings没有不管是不是,你永远无法解决这个问题,KeyListener 是最重要的,主要问题和取决于......,直到你包括使用 SSCCE 编辑你的帖子,以获得更好的帮助来检查通过鼠标点击发布到keylistener
  • 使用 Swing Timer 延迟来自任何 Listener 的事件没有问题,

标签: java swing awt keylistener


【解决方案1】:

感谢大家的回答!他们帮助我走上正轨。

正如我在评论中所说,这里发生的情况如下: 例如,如果我们按住右键 - 角色向右移动,那么我们按下左键,它开始向左移动。现在,如果我们松开右键,xSpeed 将重置为零,KeyListener 必须等到再次触发keyPressed(),因为我们仍然按住左键。 “按键重复速度”是默认设置的,据我了解无法调整。

所以解决方案是跟踪当前按下了哪些键,这样当我们仍然按住左键时,我们不必在释放右键时将角色的速度降为零。

抱歉,举了一个有点神秘的例子,只是尽量保持代码小:

// Define keys: up, right, down, left
// 0 - not pressed, 1 - pressed
private int[] keys = {0, 0, 0, 0};

// player control
public void keyPressed(KeyEvent e) {
    int key = e.getKeyCode();
    // we set the corresponding 'key indicator' to 1 when it is pressed
    switch(key){
        case(KeyEvent.VK_LEFT): dx = -speed; keys[3] = 1; break; 
        case(KeyEvent.VK_RIGHT): dx = speed; keys[1] = 1; break;
        case(KeyEvent.VK_UP): dy = -speed; keys[0] = 1; break;
        case(KeyEvent.VK_DOWN): dy = speed; keys[2] = 1; break;
        case(KeyEvent.VK_SPACE): fireOn = true; break;
    }
}

public void keyReleased(KeyEvent e) {
    int key = e.getKeyCode();
    // now before resetting the speed we check if the opposite key
    // is still pressed
    switch(key){
        case(KeyEvent.VK_LEFT): if(keys[1]==0){dx = 0;} keys[3] = 0; break;
        case(KeyEvent.VK_RIGHT): if(keys[3]==0){dx = 0;} keys[1] = 0; break;
        case(KeyEvent.VK_UP): if(keys[2]==0){dy = 0;} keys[0] = 0; break;
        case(KeyEvent.VK_DOWN): if(keys[0]==0){dy = 0;} keys[2] = 0; break;
        case(KeyEvent.VK_SPACE): fireOn = false; break;
    }
}

【讨论】:

【解决方案2】:

另一种方法可能会有所帮助:

object.addKeyListener(new KeyAdapter() {
    @Override
    public void keyTyped(KeyEvent e) {
        updateOpreation();
    }

    @Override
    public void keyReleased(KeyEvent e) {
        updateOpreation();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        updateOpreation();
    }

}

【讨论】:

  • 为什么会有帮助?
猜你喜欢
  • 2013-11-06
  • 2013-06-08
  • 2015-03-13
  • 2017-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
  • 1970-01-01
相关资源
最近更新 更多