【DXライブラリ】キーボードの入力状態を取得する

ゲームを作るうえで絶対に欠かせないキーボードの入力状態を取得する方法について説明しています。これができなければメニューの選択ができないし、キャラも動かせません。

特定のキーが押されているかどうかだけを知る

特定のキーが押されているかどうか知りたいだけなら CheckHitKey() を使う。

宣言 int CheckHitKey( int KeyCode)
概要 特定キーの入力状態を得る
引数 KeyCode 入力状態を取得するキーコード
戻り値 1 押されている
0 押されていない

DXライブラリ導入記事のテストコードですでに使っている関数で、キーコードをこの関数に渡してそのキーコードの入力状態を返すというもの。キーコードについてはこちら

以下はESCキーの入力状態を得るサンプルコード。

#include "DxLib.h"

//中略

if (CheckHitKey(KEY_INPUT_ESCAPE) != 0) {
 //ここに特定のキーが押されていた場合の処理を書く
}

ただしこの方法だと何フレーム押されているかまでは取得できないので次の方法を使う。

押された・離された瞬間や何フレーム押されているか知る

アクションや格闘ゲームでため撃ちなどの動作を入れる場合、何フレーム押されているかを知る必要がある。他にもキーが押された瞬間や離された瞬間を知りたい場合もあると思う。

これらを実装するには自分でこのキーが何フレーム押されているかどうかを格納する配列を用意する。

さっそくサンプルコードをペタリ。

#include "DxLib.h"

int Input_Keyboard[256]; //キーが押されているフレーム数を格納する

//キーボードの入力状態を更新する
void Input_UpdateKeyboard() {
    int i;

    char tmpKey[256];   //現在のキーボードの入力状態を格納する

    // 全てのキーの入力状態を得る
    GetHitKeyStateAll(tmpKey);

    for (i = 0; i < 256; i++) {
        if (tmpKey[i] != 0) { // i番のキーコードに対応するキーが押されていたら
            Input_Keyboard[i]++;     // 加算
        }
        else {              // 押されていなければ
            if (Input_Keyboard[i] > 0) {    //前フレームで対応するキーが押されていれば
                Input_Keyboard[i] = -1;   // -1にする。-1はキーが離された時用の値
            }
            else {
                Input_Keyboard[i] = 0;   // 0にする
            }
        }
    }
}

//指定のキーが押された瞬間か調べる
bool Input_GetKeyboardDown(int KeyCode) {
    if (Input_Keyboard[KeyCode] == 1) return true;
    return false;
}

//指定のキーが押されているか調べる。返り値は押されているフレーム数
int Input_GetKeyboard(int KeyCode) {
    return Input_Keyboard[KeyCode];
}

//指定のキーが離された瞬間か調べる
bool Input_GetKeyboardUp(int KeyCode) {
    if (Input_Keyboard[KeyCode] == -1) return true;
    return false;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // ウィンドウモードに設定
    ChangeWindowMode(TRUE);

    // DXライブラリ初期化処理
    if (DxLib_Init() < 0) {
        //エラーなら終了する
        return -1;
    }

    //描画先を裏画面にする
    SetDrawScreen(DX_SCREEN_BACK);

    // 画面モードの変更
    SetGraphMode(1280, 720, 32);

    // while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
    while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {

        //キーボードの入力状態を更新
        Input_UpdateKeyboard();

        DrawFormatString(0, 0, GetColor(255, 255, 255), "ESCキー長押しで終了します");

        //ESCキーが30フレーム以上押されていれば終了
        //押された瞬間で判定する場合は if(Input_GetKeyboardDown())
        //離された瞬間で判定する場合は if(Input_GetKeyboardUp())  とする
        if (Input_GetKeyboard(KEY_INPUT_ESCAPE) > 30) {
            break;
        }

    }

    DxLib_End();    // DXライブラリ終了処理

    return 0;
}

まずメイン関数にwhile文を追加する。以降ゲームの処理は基本 while文の中に書き込んでいくことになる。while()にある制御式はエラー処理関連。

次に全部のキー入力状態を格納する配列 int Input_Keyboard[256] を定義。

そして Input_UpdateKeyboard() 内で GetHitKeyStateAll() で全部のキーの入力状態を取得し、for文で回してi番のキーコードに対するキーが押されていたら Input_Keyboard[i] に1を加算、押されていなければ0にする。

宣言 int GetHitKeyStateAll( char *KeyStateBuf)
概要 キーボードの全キーの入力状態を取得する
引数 char *KeyStateBuf 全キーの入力状態を格納するバッファのポインタ
戻り値 0 成功
1 エラー発生

0にする際 Input_Keyboard[i] の値が0より大きければ「離された瞬間」とし、0ではなく-1とする。

最後に Input_GetKeyboardDown() / Input_GetKeyboard() / Input_GetKeyboardUp() のどれかを使って特定のキーの状態を取得する。上のサンプルコードでは Input_GetKeyboard() を使い、ESCキーが30フレーム以上押されていれば終了する内容としている。

文字入力(タイピング)用のキー入力

タイピングゲームなど文章を入力する場合は GetInputChar() を使う。

宣言 char GetInputChar( int DeleteFlag)
概要 文字入力バッファにある文字データから1文字取得
引数 int DeleteFlag 取得した文字をバッファから削除するかのフラグ
戻り値 0 バッファにデータがない
それ以外 文字コードもしくは操作コード

以下のコードはDXライブラリ置き場からのサンプルコード。入力された文字を画面に表示するもの。

#include "DxLib.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  char String[2];
  char InputChar;

  // ウィンドウモードに設定
  ChangeWindowMode(TRUE);

  // DXライブラリ初期化処理
  if (DxLib_Init() < 0) {
    //エラーなら終了する
    return -1;
  }

  //描画先を裏画面にする
  SetDrawScreen(DX_SCREEN_BACK);

  // 画面モードの変更
  SetGraphMode(800, 600, 32);

  String[1] = 0;

  // while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
  while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {

    DrawFormatString(0, 0, GetColor(255, 255, 255), "ESCキーで終了します");

    // 文字入力バッファから文字を取得する
    InputChar = GetInputChar(TRUE);

    // 操作コード以外の文字入力があった場合のみ表示処理を行う
    if (InputChar != 0 && InputChar >= CTRL_CODE_CMP)
    {  
      // 文字の保存
      String[0] = InputChar;

      // 描画
      DrawString(400, 300, String, GetColor(255, 255, 255));
    }

    if (CheckHitKey(KEY_INPUT_ESCAPE) != 0) {
      break;
    }

  }
  
  DxLib_End();    // DXライブラリ終了処理
  return 0;
}

似た関数としてGetInputCharWaitがあるが、こちらはキー入力があるまで他の処理が始まらないので使わないのが無難。

ちなみにString[1] = 0;の部分をなくすと文字化けしたString[1]の中身が出てくるので注意。

補足:同時押しについて

作るゲームの内容によっては3つ以上キーを同時押しする場面が出てくるかもしれない。その時に注意してほしいのが一般的にキーボードは同時押し制限があり、正しくキー入力が反映されない場合があること。

これはハード側の仕様であり、DXライブラリの不具合ではないことに注意。

コメント

タイトルとURLをコピーしました