如何使 KeyListener 起作用?

How to make the KeyListener functional?

我正在学习 java,并尝试创建一个小乒乓球游戏作为对我的小测试,但我无法使键 right/left 箭头在我的代码中起作用,并且我遵循了一些教程,但仍然无法正常工作。

我的敌人和游戏中的球工作得很好,一切都有碰撞,但我仍然无法使 controls/keys 工作。

这是我正在使用的代码和我的 class 播放器(我认为这里有错误,但我仍然不知道如何找到它)。

代码

public void keyPressed(KeyEvent e) {    
        if(e.getKeyCode() == KeyEvent.VK_RIGHT)
            player.right = true;        
        
            else if(e.getKeyCode() == KeyEvent.VK_LEFT)
                player.left = true;
    }

    public void keyReleased(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_RIGHT)
            player.right = false;
        
            else if(e.getKeyCode() == KeyEvent.VK_LEFT)
                player.left = false;
    } 

Class“玩家”

public class Player {

    public boolean right,left;
    public int x,y;
    public int width,height;
    
    public Player(int x, int y) {
        this.x = x;
        this.y = y;
        this.width = 40;
        this.height = 10;
    }
    
    public void tick() {
        if(right) {
            x++;
        }
        else if(left) {
            x--;
        }
        if(x+width > Game.WIDTH) {
            x = Game.WIDTH - width;
        }
        else if(x < 0) {
            x = 0;
        }
    }

    public void Render(Graphics g) {
        g.setColor(Color.blue);
        g.fillRect(x, y, width,height);
    }
}

这个小例子有一个 KeyListener 有效。玩家没有移动,因为没有调用Player.tick方法。

// Pong.java

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class Pong {
    public static void main(String[] arguments) {
        SwingUtilities.invokeLater(() -> new Pong().createAndLaunchGui());
    }

    private void createAndLaunchGui() {
        JFrame frame = new JFrame("Pong");
        frame.setBounds(240, 160, Game.WIDTH, Game.HEIGHT);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(new Game());
        frame.setVisible(true);
    }
}


// Game.java

import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;

public class Game extends JPanel {
    public static int WIDTH = 800;
    public static int HEIGHT = 600;

    private final Player player = new Player(400, 300);

    public Game() {
        setFocusable(true);

        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent keyEvent) {
                System.out.println("Game.keyPressed -- event: " + keyEvent);

                if (keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) {
                    player.right = true;
                } else if (keyEvent.getKeyCode() == KeyEvent.VK_LEFT) {
                    player.left = true;
                }
            }

            @Override
            public void keyReleased(KeyEvent keyEvent) {
                System.out.println("Game.keyReleased -- event: " + keyEvent);

                player.right = false;
                player.left = false;
            }
        });
    }

    @Override
    protected void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);

        player.render(graphics);
    }
}

解决您的问题的关键可能是在 Game class 的构造函数中调用 setFocusable(true) 方法。如本 Stack Overflow answer 中所述,事件仅分派到具有焦点的组件。请参阅该答案了解更多详细信息,并在博客 post 中查看 link 并提供详尽的解释。