0

私は C++ でのプログラミングの初心者で、2 週間、同じキーボードで 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);

}

この関数を loop-while 内で使用して、各フレームでプレイヤーが何を押しているかに応じて各宇宙船を動かしています。

ただし、特定のキーのミックスを使用している場合、プログラムは一部のキーを処理しません (そのため、ブール配列 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