0

我创建了一个静态 Input 类,它基本上有一个我可以调用的方法,它是:

public static boolean GetKeyDown(int keyCode) {
    while(Keyboard.next()) {
        Keyboard.enableRepeatEvents(false);
        if (Keyboard.getEventKeyState()) {
            if (Keyboard.getEventKey() == keyCode) {
                return true;
            } else {
                return false;
            }
        }
    }
    return false;
}

在我的游戏更新循环中,我想使用它,而不必制作一个 while 循环:

if(Input.GetKeyDown(KeyCode.S)) {
    //Something happens
}
if(Input.GetKeyDown(KeyCode.R)) {
    //Something happens
}
//etc..

但似乎只有第一个加载,才能工作。在这种情况下是“S”。有没有办法让我也可以使用其他人?

4

1 回答 1

3

那是因为在您的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 来清除前一帧的按键。

于 2013-11-07T10:28:46.163 回答