0

我在 Nifty-GUI 的事件处理方面遇到了严重问题,并在互联网上搜索了解决方案,但并没有真正找到任何解决方案(我想避免实现自己的 InputSystem)。问题是,一旦我开始在我的应用程序中使用 nifty,LWJGL 似乎不再获得任何键盘输入。我已经尝试了一些类似的东西nifty.setIgnoreKeyboardEvents(true),但它并没有改变任何东西。我知道我可能做错了什么,但我希望这里有人可以帮助我。

这些是相关的代码摘录:

UI 类负责设置 nifty。它在另一个名为 Graphics 的类中实例化(它实现了 Runnable,如果这很重要的话),但只有在 LWJGL 和 OpenGL 被初始化之后。

public class UI {

    private Nifty nifty;

    public UI() {
        initUI();
    }

    private void initUI() {
        LwjglInputSystem inputSystem = initInput();
        nifty = initNifty(inputSystem);
        nifty.setIgnoreKeyboardEvents(true);
        nifty.fromXml("resources/ClientStartScreen.xml", "start", 
                new ClientStartController());
    }

    private LwjglInputSystem initInput() {
        try {
            LwjglInputSystem inputSystem = new LwjglInputSystem();
            inputSystem.startup();
            inputSystem.niftyHasKeyboardFocus = false;
            inputSystem.niftyTakesKeyboardFocusOnClick = false;
            return inputSystem;
        } catch(Exception e) {
            System.out.println("[ERROR:] Input System could not be"
                    + "initialised.");
            System.out.println(e.getMessage());
            return null;
        }
    }

    private Nifty initNifty(LwjglInputSystem inputSystem) {
        try {
            return new Nifty(new BatchRenderDevice(
                    LwjglBatchRenderBackendCoreProfileFactory.create()),
                    new NullSoundDevice(), inputSystem, 
                    new AccurateTimeProvider());
        } catch(Exception e) {
            System.out.println("[ERROR:] Nifty could not be initialised.");
            System.out.println(e.getMessage());
            return null;
        }
    }

    public Nifty getNifty() {
        return nifty;
    }
}

我使用的屏幕是最小的例子,所以这里应该没有问题:

<?xml version="1.0" encoding="UTF-8"?>
<nifty xmlns="http://nifty-gui.lessvoid.com/nifty-gui">
    <useStyles filename="nifty-default-styles.xml" />
    <useControls filename="nifty-default-controls.xml" />

    <screen id="start"
            controller="htw.gt3.trappers.client.screens.ClientStartController">
        <layer childLayout="center">
            <text id="hellouser" font="aurulent-sans-16.fnt" color="#ffff" 
                  text="Hello user!" />
        </layer>
    </screen>

</nifty>

并且控制器不做任何事情,只有空的覆盖方法。

我正在使用一个单独的类来处理输入。它是游戏主循环的一部分(是 Graphics 类的一部分)。循环中调用的相关方法开始如下:

public void checkInput() {
    while(Keyboard.next()) {
        if(!Keyboard.getEventKeyState()) {
            if(Keyboard.getEventKey() == Keyboard.KEY_UP) {

但是,游戏永远不会进入 while 循环,因为正如我所说,键盘没有收到任何事件,因为它们可能已经被 nifty 消耗掉了。请注意,当我不使用 nifty 时,我的代码可以正常工作 - 因此,当我不在我的 Graphics 类中创建 UI 对象并且只是留在我的黑屏上没有任何内容时,我的输入工作正常。

主循环如下所示:

boolean niftyDone = false;
while(!Display.isCloseRequested() && !niftyDone) {
    controls.checkInput();
    Display.update();
    Display.sync(60);
    if(ui.getNifty().update()) {
        niftyDone = true;
    }            
    ui.getNifty().render(true);
}

我真的在这里依靠你的帮助 - 希望有人知道问题可能是什么。

4

1 回答 1

0

只要 Nifty 处于活动状态——你调用 nifty.update()——它当前就会从 LWJGL 读取键盘事件,这意味着它们将不再对你可用。这是在 LwjglInputSystem 的 processKeyboardEvents() 方法中完成的……而且……目前你无能为力。

但是,如果您设置了 nifty.setIgnoreKeyboardEvents(true) 或者 Nifty 没有处理事件(!),那么 Nifty 仍然会从 LWJGL 读取它们,但它会在内部将它们存储在队列中,您可以稍后自己读取和处理它们!

您可以调用 hasNextKeyboardEvent() 和 nextKeyboardEvent() 方法来读取事件。您可以在此处找到 LwjglInputSystem 类中的方法:https ://github.com/void256/nifty-gui/blob/1.4/nifty-renderer-lwjgl/src/main/java/de/lessvoid/nifty/renderer/lwjgl /input/LwjglInputSystem.java#L88

这样你仍然可以处理 Nifty 没有处理的键盘事件:)

PS:当然,更普遍的问题是有人赢了从 LWJGL 读取键盘事件。这要么是你的游戏,但 Nifty 不会得到它们 - 或者你需要自己将它们转发给 Nifty ... () 方法。

我们决定使用第二个选项,因为在许多情况下人们只会使用 GUI(菜单屏幕等),而不会同时激活游戏代码。因此,在这些情况下,它会增加用户手动转发事件的工作量,但使用当前的解决方案,它有点开箱即用,无需额外工作。

但是对于您需要两者的情况,我认为上面的解决方案应该可以正常工作。

于 2015-01-21T21:10:43.117 回答