[ ホーム | TSG について | 活動 / 分科会 | イベント | メンバー | メーリングリスト | 部報 | 掲示板 | リンク ]

SDL / OpenGL 分科会 - 第 3 回

前回グラフィックスの使い方を紹介しました。 しかし、ただ表示をしているだけでユーザが何も操作できないのはちょっと味気ないものです。 そこで今回はキーボードおよびジョイスティックからの入力を調べる方法を紹介します。

キーボード

まずキーボードです。 これはとても簡単。 これだけです :

Uint8 *keys=SDL_GetKeyState(NULL);
if(keys[SDLK_RETURN]==SDL_PRESSED)
    printf("return key is pressed.\n");

SDL_GetKeyState() で現在のキーボード状態を表す配列を取得できます。 この配列の各要素にキーの状態 (SDL_PRESSED (値 1) または SDL_RELEASED (値 0)) が入っています。 各キーを表す定数 (SDLK_*) の一覧については SDLKey の頁を参照して下さい。

ジョイスティック

キーボードも良いですが、ジョイスティックがあるならそちらの方が良いでしょう。 駒場祭などでゲームを展示する場合も、ジョイスティックの方がお客さんにとってはずっと使いやすいようです。

初期化

まず、SDL_Init()SDL_INIT_JOYSTICK をつけて SDL を初期化します。 例えば :

/* グラフィックスとジョイスティックを初期化 */
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK)<0) {
    fprintf(stderr,"failed to initialize SDL.\n");
    return -1;
}

SDL_Init() を済ますと、接続されているジョイスティックの状態 (個数・名前) を調べられるようになります。 それぞれ SDL_NumJoysticks(), SDL_JoystickName() を使います。

int i;
printf("%d joysticks found.\n",SDL_NumJoysticks());
printf("their names are:\n");
for(i=0; i<SDL_NumJoysticks(); i++)
    printf("%d = %s\n",i,SDL_JoystickName(i));

そして、実際にジョイスティックを使うためには、それを SDL_JoystickOpen() で開いておきます (そして、終了時には SDL_JoystickClose() で閉じます)。

SDL_Joystick *joy=SDL_JoystickOpen(0);
if(!joy) {
    fprintf(stderr,"failed to open joystick 0.");
    return -1;
}

/* … */

SDL_JoystickClose(joy);

読み取り

で、肝心の読み取りです。 まず SDL にジョイスティックの状態を更新するように指示します (SDL 内部に前回のジョイスティックの状態が保存されているので、現在のハードウェアの状態を読み込ませないといつまでも古い情報しか得られません)。 これには SDL_JoystickUpdate() を使います。 まあ基本的にはプログラムの 1 サイクルごとに呼び出せば良いでしょう。

SDL_JoystickUpdate();

そして個々のボタンを調べます。 これは簡単です。 調べるボタンの番号を指定して SDL_JoystickGetButton() を呼び出すだけです。 返り値が 1 (SDL_PRESSED) なら押されていて、0 (SDL_RELEASED) なら押されていない、ということになります。

/* SDL_Joystick *joy は予め開かれていると仮定 */
if(SDL_JoystickGetButton(joy,0)==SDL_PRESSED)
    printf("joystick: button 0 pressed\n");

ただ、実は上の処理だけでは調べられないものがあります。 それは十字キーです。

多くのジョイスティックには十字キーがついていますが、これは「ボタン」ではなく「軸」という扱いになっています。 何が違うのかというと、ボタンは「押されているか / いないか」の真偽値をとるのに対し、軸はある範囲内の数値 (具体的には -32768 から 32767 までの整数値) をとります。 こうすることでアナログのコントローラ (NINTENDO 64 のようなもの) に対応できるようになっています。 とはいってもまあ大抵のジョイスティックはデジタルで、その場合は「押されていないときは 0、押されているときは取りうる範囲の最大値 or 最小値」となることが多いようです。 アナログ・デジタルの両方に対応するためには、適当な閾値 (ボーダーライン) を設定して、その値以上なら押されている、と判定すれば良いでしょう。

軸の状態を調べるには SDL_JoystickGetAxis() を使います。 引数にジョイスティックと軸番号を与えます。 ほとんどのジョイスティックでは軸 0 が X (正が右, 負が左), 軸 1 が Y (正が下, 負が上) となっています。

/* SDL_Joystick *joy は予め開かれていると仮定 */
Sint16 axis;

/* 軸0 (X) */
axis=SDL_JoystickGetAxis(joy,0);
if(axis>=256)
    printf("joystick: right\n");
else if(axis<=-256)
    printf("joystick: left\n");

/* 軸1 (Y) */
axis=SDL_JoystickGetAxis(joy,1);
if(axis>=256)
    printf("joystick: down\n");
else if(axis<=-256)
    printf("joystick: up\n");

ということで、今回はここまでです。 とりあえずグラフィックを表示してユーザの操作に反応するような単純なプログラムは作れるようになっているのではないでしょうか。 次回もお楽しみに。