Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux/X11下的Java keyPress/keyRelease问题_Java_Linux_X11 - Fatal编程技术网

Linux/X11下的Java keyPress/keyRelease问题

Linux/X11下的Java keyPress/keyRelease问题,java,linux,x11,Java,Linux,X11,我正在用Java开发一个小型2D游戏引擎,在托管Ubuntu的VirtualBox虚拟机上玩了我的演示游戏后,我发现了一个奇怪的错误,它有时会导致游戏忽略按键这一事实。所以你向左跑,直到你突然停止移动 现在在一个真正的Ubuntu下,我找到了问题的原因。当我按住一个键时,按键按下/按键释放事件会一直发送 我的按键检查系统如下: -如果按下某个键,则将其添加到“下行列表” -如果某个键被释放,则将其添加到最上面的 -在游戏的每一帧上,从下列表中移除上列表中的键 -如果某个键仍在下行列表中,则按下该

我正在用Java开发一个小型2D游戏引擎,在托管Ubuntu的VirtualBox虚拟机上玩了我的演示游戏后,我发现了一个奇怪的错误,它有时会导致游戏忽略按键这一事实。所以你向左跑,直到你突然停止移动

现在在一个真正的Ubuntu下,我找到了问题的原因。当我按住一个键时,按键按下/按键释放事件会一直发送

我的按键检查系统如下:
-如果按下某个键,则将其添加到“下行列表”
-如果某个键被释放,则将其添加到最上面的
-在游戏的每一帧上,从下列表中移除上列表中的键
-如果某个键仍在下行列表中,则按下该键

现在,当您按下第二个键时,有时keyRelease是另一个键触发的最后一个事件,该键仍然保持,但无法以这种方式识别

有没有办法解决这个问题?真烦人

编辑
为了澄清,这是我连续按住一个键时得到的结果:
按下:87
发布:87
发布:87
按下:87
发布:87
按下:87
发布:87
按下:87
发布:87
等等

EDIT2

好的,在谷歌搜索了一段时间后,我发现这是X11服务器的一个“功能”,但我仍然不知道如何检测java中的“假”键事件。

由于解决每帧按键和在列表之间切换的方式,您可能会遇到一些冲突。为您计划按下的每个键(如右箭头、左箭头等)设置布尔值可能会更简洁一些。按下某个键时,将相应的布尔值设置为true,然后在释放该键时将其设置为false。这是在视频游戏中处理键盘控制的一种非常常见的方法

好的。。。我“修复”了它

由于X11不断触发其自动重复键事件,因此无法以忽略这些“假”事件的方式改变整个事件,您无法区分Java中的“真”和“假”事件

因此,解决方法如下。由于每个“假”keyUp事件之后都会有一个立即的keyDown事件,因此如果收到keyDown事件,只需从keyRemoveList中删除keyUp事件,如下所示:

public final void keyPressed(final KeyEvent e) {
    int key = e.getKeyCode();

    // Fix AutoKeyRepeat under X11
    if (keysRemove.contains(key)) {
        keysRemove.remove(Integer.valueOf(key));
    }

    if (!keysDown.contains(key)) {
        keysDown.add(key);
        keysPressed.add(key);
        lastKeys.add(key);
        if (lastKeys.size() > 16) {
            lastKeys.remove(0);
        }
    }
    e.consume();
}

由于“真实”键控事件之后没有立即的键控事件,因此正常处理该事件。从理论上讲,在“假”键向上和键向下之间不可能出现游戏帧。

当然,自动恢复在X11中是可配置的。只需查看命令选项r-r。 您可以使用禁用某些键代码的自动重发

$ xset -r keycode

最初我让它像那样工作。但是我需要检查一个键是否只按下了一次(所以如果你按住它,它只会触发一次),所以我想出了处理这个()的新代码,如果没有办法摆脱这个奇怪的GTK行为,我将不得不从头重写整个键盘处理。还有一个问题是,游戏可能会在一个不必要的按键释放事件之后进行检查。将按键动作放在计时器上可能更容易,而不是基于帧计时器。但这并不是真正的“可移植”我不能从Java中禁用它,所以每个玩游戏并遇到这些问题的人都必须自己禁用它。这是一个愚蠢的特性。密钥重复属于应用程序域。。操作系统涉及硬件。是的,但是你如何检测当前的真实情况呢?。。你需要一个该死的计时器来了解是否在此后很快注册了停机。真他妈的丑。Linux让我很生气。