私は 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 のドキュメント (正しくない可能性がありますか?)、キー間のすべてのミックスのロックを解除する機能、またはこの制限を回避する他の方法を検索しました。何も見つかりませんでした。キーボード入力に他のライブラリを使用する必要がありますか?
私の下手な英語 (および潜在的な間違い) で申し訳ありませんが、理解できるように最善を尽くしました。お読みいただきありがとうございます。