0

我是 C++ 编程的初学者,两周以来,我正在编写一个脚本,以便在同一个键盘上为 2 名玩家玩太空射击游戏。

对于游戏显示,我使用 NCURSES,对于键盘输入,我使用 X11。首先,我在键盘输入方面一直存在问题。

我们和朋友一起写了这个函数:

//earlier in the script :

Display *dpy; 

if (NULL==(dpy=XOpenDisplay(NULL))) {

    perror("Connexion problem");
    exit(1);

}

XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync, CurrentTime);


//the function (keysPressed is just an array to store keyboard inputs) :

void getKBinput(bool (&keysPressed)[128], Display* dpy){

    XEvent ev;
    int kc;

    if (XPending(dpy)){

        XNextEvent(dpy, &ev);

        switch (ev.type) {

            case KeyPress:

                kc = ((XKeyPressedEvent*)&ev)->keycode;
                keysPressed[kc] = true;
                break;

            case KeyRelease:

                kc = ((XKeyReleasedEvent*)&ev)->keycode;
                keysPressed[kc] = false;
                break;

            case Expose:

                while (XCheckTypedEvent(dpy, Expose, &ev));
                break;

            case ButtonPress:

            case ButtonRelease:

            case MotionNotify:

            case ConfigureNotify:

            default:

                break;

            }
        }
    }
}


//later in the script :

XUngrabKeyboard(dpy, CurrentTime);

if (XCloseDisplay(dpy)) {

    perror("You can't deconnect to the server");
    exit(1);

}

我在循环中使用这个函数来移动每艘宇宙飞船,具体取决于玩家按下每帧的内容。

但是,当我使用特定键的混合时,程序不会处理某些键(因此他没有将它们注册在布尔数组 keysPressed 中)。

例如,当玩家1同时按下“D”键和“C”键时,玩家2不能使用“向上”键或“!”键。(但玩家 2 可以同时使用“左”键和“下”键,没有问题)。

为了更好地了解这个脚本在做什么,我在一个外部文件中重写了这部分以打印按下的键和释放的键:

#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv){

    Display *dpy;
    XEvent ev;
    char * s;
    unsigned int kc;
    int quit = 0;

    if (NULL==(dpy=XOpenDisplay(NULL))) {
        perror(argv[0]);
        exit(1);
    }

    XAutoRepeatOff(dpy);

    XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync, CurrentTime);

    for (;!quit;) {

        XNextEvent(dpy, &ev);

        switch (ev.type) {

        case KeyPress:

             kc = ((XKeyPressedEvent*)&ev)->keycode;
             s = XKeysymToString(XKeycodeToKeysym(dpy, kc, 0));

             if (s) printf("KEY PRESS:%s\n", s);

             if (!strcmp(s, "q")) quit=~0;

             break;

        case KeyRelease:

             kc = ((XKeyReleasedEvent*)&ev)->keycode;
             s = XKeysymToString(XKeycodeToKeysym(dpy, kc, 0));

             if (s) printf("KEY RELEASE:%s\n", s);

        case Expose:

             while (XCheckTypedEvent(dpy, Expose, &ev));
             break;

        case ButtonPress:

        case ButtonRelease:

        case MotionNotify:

        case ConfigureNotify:

        default:

            break;

        }
    }

    XUngrabKeyboard(dpy, CurrentTime);

    XAutoRepeatOn(dpy);

    if (XCloseDisplay(dpy)) {

        perror(argv[0]);
        exit(1);

    }

    return 0;
}

这证实了我的问题。因为我的电脑很旧(而且一些键工作得非常糟糕),所以我在其他电脑上测试了这个脚本,使其落在相同的输出上。

我在 x11 文档中进行了搜索(可能不正确?),一个解锁键之间每个混合的功能或其他绕过此限制的方法。我什么也没找到。我应该使用其他库进行键盘输入吗?

对不起我糟糕的英语(和潜在的错误),我尽力让人们理解。感谢您的阅读。

4

0 回答 0