3

我正在“OpenGL”中编写游戏并使用“Gtkmm”作为窗口管理器。我想使用键盘来移动相机(因此,“向上键”向前移动,“向下键”向后移动,等等......)

前段时间,当我用 Java 编程时,我使用这种技术来“移动”:
当应用程序接收到例如“UP- keypress ”信号时,它随后将标志“shouldMoveForward”设置为“true”,当它后来收到“UP-key- release ”信号,它把标志设置回“false”。
并且“游戏循环”不断检查该标志,如果是真的,它会向前移动相机,否则它什么也不做。

所以我想在“Gtkmm”中使用相同的技术。所以我只是覆盖了我的"Gtk::DrawingArea"的这些功能:

bool Gtk::Widget::on_key_press_event(GdkEventKey* event)
bool Gtk::Widget::on_key_release_event(GdkEventKey* event)

但问题在于:例如,当我按下“UP”键并按住 5 秒钟时,会发出以下信号序列:

press  ...<little time waiting>...  release  press  release  press  release  press  release   ..........   press  release  press  release

当我在“在 Linux 上”运行我的游戏时,会出现之前的情况。

当我“在 Windows 上”时,它就像我想要的那样,因此:

press  ...<little time waiting>...  press  press  press  press  press  ..........  press  press  release

所以这似乎是在 Gtkmm 中移动相机的“非便携式”解决方案。

那么是否有任何其他(“PORTABLE”)解决方案可以使用 Gtkmm 作为窗口管理器来实现相机移动?

4

2 回答 2

2

该线程描述了问题(不在 GTK+ 本身中),以及一些解决方法。

于 2010-02-10T17:44:19.503 回答
0

我刚刚在我的java游戏中遇到了自动重复“功能”,我把它修好了。

既然您知道 java,那么移植以下代码应该不会有问题:

// Keyboard
private final List<Integer> keysPressed = new LinkedList<Integer>();
private final List<Integer> keysDown = new LinkedList<Integer>();
private final List<Integer> keysRemove = new LinkedList<Integer>();

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);
    }
    e.consume();
}

public final void keyReleased(final KeyEvent e) {
    int key = e.getKeyCode();
    keysRemove.add(key);
    e.consume();
}

public final void clearKeys() {
    for (Integer key : keysRemove) {
        keysDown.remove(Integer.valueOf(key));
        if (keysPressed.contains(key)) {
            keysPressed.remove(Integer.valueOf(key));
        }
    }
    keysRemove.clear();
    keysPressed.clear();
}

在游戏状态更新后(检查键盘输入/移动对象),方法 clearKeys 在主循环中被调用,这里的技巧是第一个 if in keyPressed。自动生成的键事件发生在完全相同的时间,因此在伪造的 keyReleased 和 keyPressed 事件之间几乎不可能发生某些事情。当 keyPressed 事件发生时,键可以在 keyRemove 列表中的唯一方法是它是一个假事件,因此在这种情况下,我们只需从 keyRemove 列表中删除该键。

当您正常释放键时,它不会紧随其后的 keyPressed 事件,因此它不会从列表中删除并由 clearKeys 处理。

对于其余的代码(比如检查一个键是否被按下或被按下)查看源代码:http: //github.com/BonsaiDen/Bonsai-Game-Library/blob/master/src/org/bonsai/开发/游戏输入.java

于 2010-02-11T04:12:47.950 回答