我用Java制作2D游戏。在播放时,控件将随机锁定,通常在30秒内,并且绑定将停止对按键的反应。控件有时会短时间返回。我使用Z,X和箭头键。单独使用箭头键似乎很好,但Z和X键似乎触发了锁定。
对于控件,我最初使用的是KeyListeners,然后是KeyEventDispatcher,然后我尝试了键绑定。它适用于所有这些,虽然KeyListeners似乎仍然触发KeyReleased事件,而不是KeyPressed。键绑定完全停止。
游戏窗口是JFrame中JPanel中的Canvas。使用面板的输入和动作映射设置绑定。
我在Mac上,最近我升级到macOS Sierra。我在升级之前就已经看到过这个问题,但升级后它变得更糟,游戏变得无法播放。我还没有在其他操作系统或其他Mac上测试过。
我发现网上有一些人似乎遇到了同样的问题,有人提交了错误报告:
https://bugs.openjdk.java.net/browse/JDK-8167263
但除此之外,我还没有找到很多解决方法。我在这一点上最好的猜测是它是一个连接到Sierra的bug,并且要么会有修复,要么我的mac上有一些需要重新配置的东西。我一直在寻找。任何建议都会很棒,因为我可能错过了重要的一步。谢谢大家!
以下是使用WASD键的可编辑示例:
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class KeyErrorTest
{
public KeyErrorTest() {}
public static void main(String[] args)
{
KeyErrorTest keyErrors = new KeyErrorTest();
keyErrors.go();
}
public void go()
{
//create panel
JPanel panel = new JPanel();
panel.setFocusable(true);
panel.requestFocusInWindow();
//set up bindings for press and release
InputMap inputMap = panel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = panel.getActionMap();
//W
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), 1);
actionMap.put(1, new KeyPresser(KeyEvent.VK_W));
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true), 2);
actionMap.put(2, new KeyReleaser(KeyEvent.VK_W));
//A
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, false), 3);
actionMap.put(3, new KeyPresser(KeyEvent.VK_A));
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, true), 4);
actionMap.put(4, new KeyReleaser(KeyEvent.VK_A));
//S
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), 5);
actionMap.put(5, new KeyPresser(KeyEvent.VK_S));
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, true), 6);
actionMap.put(6, new KeyReleaser(KeyEvent.VK_S));
//D
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), 7);
actionMap.put(7, new KeyPresser(KeyEvent.VK_D));
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, true), 8);
actionMap.put(8, new KeyReleaser(KeyEvent.VK_D));
//create frame
JFrame frame = new JFrame("Key Bindings Test");
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
System.out.println("Press [W], [A], [S], or [D] several times");
System.out.println("The error tends to occur within 30 seconds");
System.out.println("The keys will randomly stop registering");
}
private class KeyPresser extends AbstractAction
{
int key;
public KeyPresser(int key)
{
this.key = key;
}
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println((char)key+" down");
}
}
private class KeyReleaser extends AbstractAction
{
int key;
public KeyReleaser(int key)
{
this.key = key;
}
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println((char)key+" up");
}
}
}