有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JavaNiftyGUI 1.4使用键盘事件(LWJGL 2.9.2)

我在漂亮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>

控制器什么也不做,只有空的覆盖方法

我使用一个单独的类来处理输入。它是游戏主循环(图形类的一部分)的一部分。循环中调用的相关方法如下所示:

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

然而,游戏从来没有进入while循环,因为正如我所说的,键盘不会接收任何事件,因为它们可能被nifty使用过。请注意,当我不使用nifty时,我的代码可以正常工作——因此,当我在图形类中不创建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);
}

我真的很依赖你的帮助-希望有人知道问题可能是什么


共 (1) 个答案

  1. # 1 楼答案

    只要俏皮活跃,你就称之为俏皮。update()-它当前将从LWJGL读取键盘事件,这意味着它们将不再对您可用。这是在LwjglInputSystem中的processKeyboardEvents()方法中完成的。。。和目前你对此无能为力

    然而,如果你设置了俏皮。setIgnoreKeyboardEvents(true)或Nifty未处理事件(!)然后Nifty仍然会从LWJGL中读取它们,但它会在内部将它们存储在队列中,您可以稍后自己读取和处理它们

    可以调用hastNextKeyboardEvent()和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(菜单屏幕等),而不会同时激活游戏代码。因此,在这些情况下,它会为用户手动转发事件增加更多工作,但在当前的解决方案中,它有点开箱即用,无需额外工作

    但对于两种情况都需要的情况,我认为上面的解决方案应该可以很好地工作