Nifty-GUI 1.4 использует события клавиатуры (LWJGL 2.9.2)

У меня серьезные проблемы с обработкой событий в Nifty-GUI, и я искал решения в Интернете, но на самом деле не нашел ни одного (я хочу избежать реализации моей собственной InputSystem). Проблема в том, что, как только я начинаю использовать изящную программу в моем приложении, LWJGL, похоже, больше не получает ввод с клавиатуры. Я уже пробовал несколько вещей, как nifty.setIgnoreKeyboardEvents(true), но это ничего не меняет. Я знаю, что, возможно, я делаю что-то не так, но я надеюсь, что кто-то здесь может мне помочь.

Вот соответствующие выдержки из кода:

Класс пользовательского интерфейса отвечает за настройку изящных. Он создается в другом классе с именем 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, потому что, как я уже сказал, клавиатура не получает никаких событий, поскольку они, вероятно, использовались отличным образом ранее. Обратите внимание, что мой код работает правильно, когда я не использую изящные - поэтому, когда я не создаю объект пользовательского интерфейса в своем классе Graphics и просто остаюсь с черным экраном без чего-либо на нем, мой ввод работает нормально.

Основной цикл выглядит так:

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 ответ

Пока Nifty активен - вы вызываете nifty.update() - в настоящее время он будет читать события клавиатуры из LWJGL, что означает, что они больше не будут вам доступны. Это делается с помощью метода processKeyboardEvents() в LwjglInputSystem ... и... на данный момент вы ничего не можете с этим поделать.

Однако, если вы установили 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 самостоятельно... ИЛИ это Nifty, который читает событие, а затем они не доступны для вашей игры с помощью обычного Keyboard.next() подход.

Мы решили использовать второй вариант, поскольку во многих случаях люди будут использовать только графический интерфейс (экраны меню и т. Д.) Без одновременной активности кода игры. Таким образом, в этих случаях пользователю потребовалось бы больше работы по перенаправлению событий вручную, но с текущим решением это вроде бы работает из коробки без дополнительной работы.

Но для случаев, которые вам нужны, я думаю, что решение выше должно работать просто отлично.

Другие вопросы по тегам