【问题标题】:How to make the KeyListener functional?如何使 KeyListener 起作用?
【发布时间】:2021-05-19 14:41:26
【问题描述】:

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

我的敌人和游戏中的球工作正常,一切都有碰撞,但我仍然无法使控件/键工作。

这是我正在使用的代码和我的 Player 类(我认为错误出在此处,但我仍然不知道如何找到它)。

代码

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;
    } 

“玩家”类

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);
    }
}

【问题讨论】:

  • 你在注册你的按键事件监听器吗?
  • 我学习了一些教程你关注了这个tutorial 吗?
  • "(我认为错误在此处但我仍然不知道如何找到它)" 那是一个 我们敦促人们发布minimal reproducible example 的原因。根据定义,问题将出现在 MRE 中的某处。不要发布随机代码sn-ps。

标签: java swing awt keylistener


【解决方案1】:

这个小例子有一个有效的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 类的构造函数中调用setFocusable(true) 方法。正如Stack Overflow answer 中所解释的,事件仅被分派到具有焦点的组件。请参阅该答案以获取更多详细信息以及包含详细说明的博客文章链接。

【讨论】:

    猜你喜欢
    • 2016-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-14
    • 2012-01-28
    • 2013-06-14
    • 1970-01-01
    相关资源
    最近更新 更多