我正在为我的学校编写蛇,除了 keyListener 之外,一切都工作得很好。我真的不知道问题出在哪里,因为我认为我调用的方式是正确的。
这是我的窗口类的代码:
package GUI;
import Entity.Apple;
import Entity.Schlange;
import Threads.Threads;
import Threads.KeyInput;
import javax.swing.*;
public class Window extends JFrame {
public Window() {
Spielfeld spielfeld = new Spielfeld();
Apple apple = new Apple(0, 0, spielfeld);
KeyInput keyInput = new KeyInput(); // This is the keyListener
Schlange schlange = new Schlange(spielfeld, apple, keyInput);
Threads thread = new Threads(spielfeld, apple, schlange);
this.setTitle("Snake");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setResizable(false);
this.add(spielfeld);
this.pack();
this.addKeyListener(keyInput);
this.setVisible(true);
thread.startThread();
}
}
从 keyListener 中:
package Threads;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
public class KeyInput implements KeyListener {
public Queue<String> queue = new ConcurrentLinkedQueue<>();
@Override
public void keyTyped(KeyEvent e) {
String moved = new String();
System.out.println("keyTyped");
if (e.getKeyCode() == KeyEvent.VK_W) {
System.out.println("W gedrückt");
moved = "up";
} else if (e.getKeyCode() == KeyEvent.VK_A) {
System.out.println("W gedrückt");
moved = "left";
} else if (e.getKeyCode() == KeyEvent.VK_S) {
System.out.println("W gedrückt");
moved = "down";
} else if (e.getKeyCode() == KeyEvent.VK_D) {
System.out.println("W gedrückt");
moved = "right";
}
queue.add(moved);
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("keyTyped");
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("keyTyped");
}
}
keyListener 应该添加到窗口中,然后交给“Schlange”(Germ.:Snake),它将在其中进行处理。
我有很多带有 System.out.println() 的行要调试,但它们都没有给出任何内容,而且我单击什么并不重要。
我应该将其添加到 JPanel 中吗?
我可以提示三点:
不要为不同的事件向 sysout 写入相同的消息,这会让您感到困惑,因此,为每个方法写下其真实名称并添加参数:
System.out.println("KeyInput.keyTyped(e=" + e + ")");
System.out.println("KeyInput.keyPressed(e=" + e + ")");
System.out.println("KeyInput.keyReleased(e=" + e + ")");
)。这样您将看到在哪里触发了什么。
这非常重要,因为某些键不会触发所有 3 个事件(按下、释放、键入)。
如果您不添加面板
spielfeld
,事件实际上都会被触发。由于我看不到您的 Spielfeld
类是什么,我打赌它会捕获(“消耗”)这些事件。
快速修复:不要将按键侦听器添加到
this
(this.addKeyListener(keyInput);
),最好将它们添加到 spielfeld
:spielfeld.addKeyListener(keyInput);
,也许这样就可以了。
(下次请提供所有相关代码)
其实是一堆小问题:你没有描述你的实际问题。事件根本不会被触发吗?您收到什么输出消息?也许某个地方存在与此问题相关的吞咽异常。包含一个包含所有相关类的可运行示例。通常,当你简化问题时,你会自己看到解决方案。
所以,我希望这已经有所帮助。无论如何,请更新您的问题,这样如果后代来这里寻找同样的问题,他们将获得更好的信息。