DXライブラリでゲームプログラミングをする際必ず必要となるキーボードの入力状態を取得する方法についてあれこれ。押された瞬間・離された瞬間にも対応。
キーボードの入力状態を取得したい
ゲームを作るうえで絶対に欠かせないのがキーボードの入力状態(以下キー入力)を取得すること。これができなければメニュー選択もキャラを動かすこともできない。
キー入力の取得といってもいくつか種類があって
- 特定のキーが押されている瞬間を知りたい
- 特定のキーが何フレーム押されているか知りたい
- 特定のキーが離された瞬間を知りたい
- 文字入力(タイピング)できるようにしたい
それぞれで書くべきコードが変わってくるので簡単に紹介していく。
特定のキーが押されているかどうかだけを知る
単に特定のキーが押されているかだけを知りたい場合はDXライブラリで最初から用意されている関数を使う。
使用する関数はCheckHitKey。この関数にキーコードを渡して入力状態を取得する。キーコードについてはこちら。
下は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; }
内容はESCAPEキーが30フレーム以上押されていれば終了するもの。
文字入力(タイピング)用のキー入力
タイピングゲームなど文章を入力する場合はGetInputChar関数を使う。以下のコードは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ライブラリの不具合ではないことに注意。
コメント