【问题标题】:KeyListener how to handle multiple keys pressed?KeyListener如何处理多个按键被按下?
【发布时间】:2021-07-08 00:18:27
【问题描述】:

所以我在 Java 中有一个键侦听器,它在 JFrame 上向上、向下、向左或向右移动一个矩形,我使用 W、A、S 和 D 键来移动它。通常,尤其是在游戏中,按 2 个键应该会产生对角线移动。例如,您同时按下 W 和 D,预期的行为是向右斜向上移动。但是,按键侦听器一次只能检测到一个按键。我知道我可以做一些事情,一次检测多个键,然后编写新代码,就好像它是一个新键一样,但是有没有办法同时在两个不同的键下执行两段代码?如果没有,如何一次测试多个键?

这是一个最小可重复性,它设置了一个随 W、A、S 和 D 键移动的矩形。

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class Test extends JPanel implements KeyListener {
    
    private int x = 200, y = 200;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new Test().create();
    }
    
    public void paintComponent(Graphics tool) {
        super.paintComponent(tool);
        tool.drawRect(x,  y, 50, 50);
    }
    
    public void create() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        
        frame.add(this);
        frame.addKeyListener(this);
        
        frame.setVisible(true);
    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
        switch(e.getKeyCode()) {
        case KeyEvent.VK_W:
            y -= 3;
            break;
        case KeyEvent.VK_S:
            y += 3;
            break;
        case KeyEvent.VK_A:
            x -= 3;
            break;
        case KeyEvent.VK_D:
            x += 3;
            break;
        }
        repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }

}

【问题讨论】:

  • 好吧,如果一个键被按下但没有释放它仍然被按下,对吧?只是保持一点状态。
  • @Maarten Bodewes 感谢您的回复。我一般是编程新手。我该怎么做呢?
  • 创建KeyEvent 整数的Set<Integer>,按下时添加事件,释放时移除。并在需要时对其进行测试。
  • this 能解决你的问题吗?
  • @Maarten Bodewes 我想是的。所以现在我可以跟踪我有哪些键,我可以在我的代码中执行键吗?很像 JButton.doClick() 的工作原理。

标签: java swing key keylistener


【解决方案1】:

所以在@Maarten Bodewes 的一些建议之后,我想出了这个解决方案:

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;

public class Test extends JPanel implements KeyListener {
    
    private int x = 200, y = 200;
    
    Set<Integer> keys = new HashSet<Integer>();

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new Test().create();
    }
    
    public void paintComponent(Graphics tool) {
        super.paintComponent(tool);
        tool.drawRect(x,  y, 50, 50);
    }
    
    public void create() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        
        frame.add(this);
        frame.addKeyListener(this);
        
        frame.setVisible(true);
    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
        keys.add(e.getKeyCode());
        multiKeys();
        repaint();
    }
    
    public void multiKeys() {
        System.out.println(keys.size());
        for(Integer key: keys) {
            System.out.println(key);
            switch(key) {
            case KeyEvent.VK_W:
                y -= 3;
                break;
            case KeyEvent.VK_S:
                y += 3;
                break;
            case KeyEvent.VK_A:
                x -= 3;
                break;
            case KeyEvent.VK_D:
                x += 3;
                break;
            }
        }
    }


    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
        keys.remove(e.getKeyCode());
        
    }

}

现在,当我按下 W 和 D 时,矩形按预期沿对角线移动。这是因为名为 keys 的 Set 存储按下的键,然后通过一个名为 multiKeys() 的单独方法执行这些键的代码,该方法循环 keys。当然,当不再按下某个键时,通过 KeyListener keyReleased() 方法将其从 keys 设置中删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-12
    • 2011-02-07
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    • 2021-05-07
    相关资源
    最近更新 更多