【发布时间】:2017-03-15 03:40:51
【问题描述】:
我正在使用 RealTutsGML 的教程制作游戏,所以如果你看过他 2013 年的一些旧视频,你会看到这段代码的大纲来自哪里。
(顺便说一下,我对 Java 并不陌生,但我对 AWT 和 Swing 以及所有这些都相当陌生,因为我曾经/现在有时会编写 Minecraft Bukkit/Spigot 插件。我可以理解相当多的Java 常规语言/语法,但 AWT 和 Swing...)
无论如何,我正在使用 KeyAdapter 来控制按键。但是,它一开始可以工作,然后随机停止工作。我调试过了,好像不是游戏中的对象,是KeyAdapter。我已经查找了一些其他解决方案,人们说它失去了焦点或其他东西,我应该使用 KeyBindings 代替。这很奇怪,因为 KeyListener RANDOMLY 停止为我工作。
无论如何,这是我正在使用的代码:
Handler handler;
public KeyInput(Handler handler){
this.handler = handler;
}
public void keyPressed(KeyEvent e){
int key = e.getKeyCode();
for (int i = 0; i < handler.object.size(); i++){
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ObjectId.Player){
if (key == KeyEvent.VK_SPACE && !tempObject.isJumping()){
tempObject.setJumping(true);
tempObject.setVelY(-10);
}
if (key == KeyEvent.VK_Y){
tempObject.setY(100);
}
if (key == KeyEvent.VK_A){
System.out.println("Pressed A");
tempObject.setVelX(-5);
}
if (key == KeyEvent.VK_D){
System.out.println("Pressed D");
tempObject.setVelX(5);
}
}
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
for (int i = 0; i < handler.object.size(); i++) {
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ObjectId.Player) {
if (key == KeyEvent.VK_D) {
for (int velX = (int) tempObject.getVelX(); velX >= 0; velX--) {
tempObject.setVelX(velX);
}
}
if (key == KeyEvent.VK_A) {
for (int velX = (int) tempObject.getVelX(); velX <= 0; velX++) {
tempObject.setVelX(velX);
}
}
}
}
}
如您所见,我正在使用 KeyAdapter 来执行此操作。这是我在主类中的初始化方法:
private void init(){
WIDTH = getWidth();
HEIGHT = getHeight();
handler = new Handler();
handler.addObject(new Player(100, 100, handler, ObjectId.Player));
handler.createTestLevel();
this.addKeyListener(new KeyInput(handler));
}
init 方法在 "this.requestFocusInWindow()" 之前被调用
我查阅了一些相关信息,发现 KeyBindings 可以解决其他人的问题。但是,我认为您必须向 JComponents 添加键绑定,而我不知道如何在游戏中获得其中之一。 new JComponent() 不起作用,我的 JFrame 正在添加我的主类(我相信它充当组件,而不是 JComponent)。
如果有人可以提供帮助,那就太好了!谢谢!
编辑#1:
我切换到 KeyBindings!这是 KeyInput 类:
Handler handler;
public JComponent component;
public KeyInput(Handler handler, JComponent component){
this.handler = handler;
this.component = component;
register();
}
public void register(){
Actions actions = new Actions();
component.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressSpace");
component.getActionMap().put("pressSpace", actions.pressSpace());
component.getInputMap().put(KeyStroke.getKeyStroke("A"), "pressLeft");
component.getActionMap().put("pressLeft", actions.pressLeft());
component.getInputMap().put(KeyStroke.getKeyStroke("released A"), "releaseLeft");
component.getActionMap().put("releaseLeft", actions.releaseXMovement());
component.getInputMap().put(KeyStroke.getKeyStroke("D"), "pressRight");
component.getActionMap().put("pressRight", actions.pressRight());
component.getInputMap().put(KeyStroke.getKeyStroke("released D"), "releaseRight");
component.getActionMap().put("releaseRight", actions.releaseXMovement());
}
public JComponent finish(){
return component;
}
public class Actions{
public Actions() { }
public Action pressRight(){
Action action = new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < handler.object.size(); i++){
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player){
temp.setVelX(5);
System.out.println("pressed right debug");
}
}
}
};
return action;
}
public Action releaseXMovement(){
Action action = new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < handler.object.size(); i++){
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player){
temp.setVelX(0);
}
}
}
};
return action;
}
public Action pressLeft(){
Action action = new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < handler.object.size(); i++){
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player){
temp.setVelX(-5);
}
}
}
};
return action;
}
public Action pressSpace(){
Action action = new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < handler.object.size(); i++){
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player){
if (!temp.isJumping()){
temp.setJumping(true);
temp.setVelY(-10);
}
}
}
}
};
return action;
}
}
但是,我仍然遇到同样的冻结问题。调试消息不会被发送,这意味着它与我的 setVel 方法没有任何关系。我不知道为什么监听器停止工作...... (起初它可以工作,但随着我不断按键,它最终会停止)。
这是我获得 JComponent 的方式:
JComponent comp = (JComponent) frame.getContentPane();
KeyInput input = new KeyInput(handler, comp);
frame.add(input.finish());
【问题讨论】:
-
如果您需要更具体的帮助,那么根据我的回答,您需要创建并发布有效的minimal reproducible example 作为对当前问题的编辑。与往常一样,代码应该以代码格式的文本而不是链接形式发布。
-
查看编辑以回答您问题的底部。同样,MCVE 的帮助是不可估量的。
-
@HovercraftFullOfEels 不在链接中是什么意思?我的帖子中没有任何链接。
标签: java swing awt keylistener key-bindings