我在Nifty-GUI的事件处理方面遇到了很多问题,并在互联网上寻找解决方案,但没有真正发现任何问题(我想避免实现自己的输入系统)。问题是,一旦我开始对我的应用程序使用漂亮,LWJGL似乎不再获得任何键盘输入。我已经尝试了一些像nifty.setIgnoreKeyboardEvents(true)
这样的东西,但它没有改变任何东西。我知道我可能做错了什么,但我希望有人可以帮助我。
以下是相关的代码摘录:
UI类负责设置漂亮。它在另一个名为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时,我的代码可以正常工作 - 所以当我不在我的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);
}
我真的很依赖你的帮助 - 希望有人知道问题是什么。
答案 0 :(得分: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 ......或者它是Nifty读取事件然后它们不是使用常规的Keyboard.next()方法为您的游戏提供。我们决定使用第二个选项,因为在很多情况下,人们只会使用GUI(菜单屏幕等)而不会同时激活游戏代码。因此,在这些情况下,它会为用户添加更多工作以手动转发事件,但使用当前的解决方案,它可以开箱即用而无需额外的工作。
但是对于你需要两者的情况,我认为上面的解决方案应该可以正常工作。