那是因为在您的GetKeyDown()
方法中,您调用Keyboard.next()
,当您调用该方法时,它会从 中删除Event
当前键的Keyboard
,当您调用时,唯一会重新填充事件Display.update();
注意:此方法不会向操作系统查询新事件。为此,必须首先调用 Display.processMessages()(或 Display.update())。
资料来源:LWJGL 文档
你可以
相反,您可以使用Keyboard.isKeyDown(int key)方法来实现您想要做的事情。
虽然它根据以下情况返回真/假。
返回:如果键根据上次 poll() 关闭,则返回 true
但这仍然不能完全解决问题,因为它依赖于poll()
方法。
解决问题
您可以通过创建一些与Keyboard
该类一起使用的自定义方法来解决问题,就像您已经做过的那样,尽管如前所述,键盘事件仅在您调用该Display.update();
方法时才会更新。
您已经对要创建哪个函数有了正确的想法,尽管您需要将它们分成两种不同的方法。您需要一个辅助方法,每次要更新键盘时调用一次。
public class MyKeyboard {
/*
* Remember that the index where we store the value,
* is the index of the key. Thereby one key might have
* an index of 400, then your array need to have at least
* the same size, to be able to store it.
*/
public static boolean[] keys = new boolean[100]; // 100 is the amount of keys to remember!
public static void update() {
while(Keyboard.next()) {
if (Keyboard.getEventKey() < keys.length) {
keys[Keyboard.getEventKey()] = Keyboard.getEventKeyState();
}
}
}
public static boolean isKeyDown(int key) {
if ((key > 0) && (key < keys.length)) {
return keys[key];
}
return false;
}
}
MyKeyboard.update()
请记住每次只调用一次该方法,Display.update()
我还将您的GetKeyDown()
方法重命名为isKeyDown()
,因为我认为这听起来和描述它更好,但如果您愿意,您可以在项目中再次重命名它。
上面的代码是在这个答案中制作的,没有使用 IDE 等。因此,如果有任何问题,我深表歉意,但只需发表评论,我会修复它。
这种方法出现的一个问题是缺乏重新检查。因为Keyboard.next()
只检查当前帧中出现的输入。曾经按下的按钮将保持“按下”状态,直到再次按下。我在尝试实施此解决方案时遇到了这个问题。这个新问题的答案在这里:
public static void update() {
for(int i = 0; i < keys.length; i++) {
keys[i] = false;
}
while(Keyboard.next()) {
keys[Keyboard.getEventKey()] = Keyboard.getEventKeyState();
}
}
您必须通过将所有内容设置为 false 来清除前一帧的按键。