7-1 キー入力について

ここではゲームを操作するためのキー入力方法について説明します。

一般のゲームではコントローラーを使いますが、パソコンでは全ての人がコントローラーを持っているわけではありません。
そこでパソコンで入力が可能な機器として最低キーボードで操作できることが必須条件となります。
※ADVなどマウスを使うのはここでは扱いません

Windowsの仕様では通常はキーボード入力はイベントとしてプログラムに通知されますが、
これだと遅延が発生したり同時キーの判定が難しいためゲームには使うのは困難です。

ただし幸いなことにWindowsにはイベント方法とは別にキーボードの入力を取得できる関数が用意されています。
この関数は同時キー入力にも対応しているため始めはこの関数を利用した入力方法を説明します。
というか、キーボードのみを使うゲームであればこの方法のみで事足ります。

■GetKeyboardState関数

GetKeyboardState関数はWindowsの標準関数であり、
Windows.hをインクルードしたプログラムはどの場所でも実行することができます。
※ただしWindowsメッセージは必ず処理すること

GetKeyboardState関数は引数に256個分のBYTE型配列を渡すだけで、
現在のキーボードの状態を一度に取得することが出来ます。

BYTE key[256];
GetKeyboardState( key );


この関数を呼び出すと仮想キーコードと呼ばれる0~255までの値を、
keyの配列番号とした挿下状態が記録されます。

たとえばスペースキーはVK_SPACE=0x20というキーコードが定義されており、
スペースが押されているかを判断するには以下のように配列番号にキーコードを入れて比較します。

if( key[VK_SPACE]&0x80 ) {
    // スペースが押されている時の処理
}

さらに挿下されているかどうかは上位ビットが立っているかで把握する必要があるため、ここでは0x80をアンドしています。
仕様ではその他のビットは別な意味に使われることがあるため、挿下を判断するためには必ず0x80をアンドしなければなりません。

VKと定義された定数はWinUser.hにありますが、実はA~Z、0~9は登録されていません。
これは文字コードがそのままキーコードになっているため、
以下のように直接文字をキーコードとして配列にアクセスすることで判定が可能です。

if( key['A']&0x80 ) {
    // Aキーが押されている時の処理
}

なお小文字の'a'ではキーコードが異なってしまうため、ここでは必ず大文字で記述します。


■ESCで終了させるサンプル

ESCのキーコードはVK_ESCAPEと定義されているので、
これでチェックを行うことでループから抜けることが出来ます。

    MSG msg;
    while(1) {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            if (msg.message == WM_QUIT) {
                DEBUG("WM_QUIT\n","");
                break;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        BYTE key[256];
        GetKeyboardState( key );

        if( key[VK_ESCAPE]&0x80 )
            break;

        Sleep(3);
    }


これでキー入力の基本的な概要は終了ですが、次のDirectInputではジョイスティックを
扱うゲームを作る必要がある場合に使えばよいので、ゲームの仕様によっては
DirectInputを無理に使う必要は無いかもしれません。