我在Java Swing中制作Arkanoid游戏。当我运行游戏时KeyEvent
无效。
为什么游戏没有检测到关键事件?
我的程序中的主类创建一个框架(JFrame
)。我还有Manage
课程来管理我游戏中的所有课程。
这是代码:Player
类是我游戏中的paddle类。
//imports
public class Player extends JPanel implements ActionListener, KeyListener
{
private int x, y, width, height;
private Timer timer;
private int fps = 60;
private int delay = 1000/fps;
public Player(int x, int y, int width, int height)
{
//setFocusable(true);
addKeyListener(this);
this.x = x;
this.y = y;
this.width = width;
this.height = height;
timer = new Timer(delay, this);
timer.start();
}
@Override
public void actionPerformed(ActionEvent e)
{
timer.start();
repaint();
}
@Override
public void keyPressed(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_A:
if (x <= 0) {
x = 0;
} else {
x -= 3;
}
break;
case KeyEvent.VK_D:
if (x >= 600) {
x = 600;
} else {
x += 3;
}
break;
}
}
public void paint(Graphics g)
{
g.setColor(Color.BLUE);
g.fillRect(x, y, width, height);
}
@Override
public void keyTyped(KeyEvent e) { }
@Override
public void keyReleased(KeyEvent e) { }
}
答案 0 :(得分:-1)
该代码的主要问题是自定义绘制的组件既不可聚焦也不集中(因此无法接收关键事件)。
此代码修复了这些问题以及更多问题(请查看代码注释以获取详细信息)。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Player extends JPanel implements ActionListener, KeyListener {
private int x, y, width, height;
private final Timer timer;
private final int fps = 60;
private final int delay = 1000 / fps;
public Player(int x, int y, int width, int height) {
addKeyListener(this);
this.x = x;
this.y = y;
this.width = width;
this.height = height;
timer = new Timer(delay, this);
timer.start();
// a component must be focusable to get key events!
setFocusable(true);
}
@Override
public void actionPerformed(ActionEvent e) {
//timer.start(); // Timer should already be started!
repaint();
}
@Override
// correct method for custom painting a JComponent is paintComponent!
public void paintComponent(Graphics g) {
// call the super method to ensure previous paints are erased!
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(x, y, width, height);
}
@Override
// a custom painted component should suggest a size to be used by the
// layout manager
public Dimension getPreferredSize() {
return new Dimension(400,100);
}
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_A:
if (x <= 0) {
x = 0;
} else {
x -= 3;
}
break;
case KeyEvent.VK_D:
if (x >= 600) {
x = 600;
} else {
x += 3;
}
break;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
public static void main(String[] args) {
Runnable r = () -> {
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationByPlatform(true);
Player player = new Player(2, 2, 5, 20);
f.setContentPane(player);
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
// a component must be focused to detect key events!
player.requestFocusInWindow();
};
SwingUtilities.invokeLater(r);
}
}