こんにちは。プログラミング初心者ですが、記事を書いてみようと思います。
これよりももっといい感じの方法があるかもです。その場合はご教示お願いします。
動作
▲ DOWN: キーが押された瞬間 / UP: キーが離された瞬間
(space_cnt: スペースキーが押されているフレーム数)
こんな感じです。
しくみ
- __前のフレームと今のフレームの入力状態を比較__して判定しています。
- 入力状態は、DxLibの関数 CheckHitKeyStateAll() を使用します。
- 入力状態の比較は__ビット演算__を活用して判定します。
ビット演算
・押された瞬間 = 前フレームが 0 + 現フレームが 1
・離された瞬間 = 前フレームが 1 + 現フレームが 0
(入力状態: 押されている状態 = 1 / 離されている状態 = 0)
●図式化したもの ![key_onoff.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2419795/29a3c07d-61ee-b283-928b-c5f23974d4ab.png)
表の内容を詳しく説明します。
__前フレームと現フレームのXOR__で、__押された瞬間・離された瞬間__が分かります。
しかし、XORのみだと、押された瞬間・離された瞬間を区別できません。
なので、
① __XORと前フレームのAND__で__押された瞬間__を求める。
② __XORと現フレームのAND__で__離された瞬間__を求める。
要点まとめ
・押された瞬間 / 離された瞬間はXORを使って求める
・XORのみだと区別できないので、ANDを使ってそれぞれ求める
↓
・押された瞬間・離された瞬間(XOR) = 前フレーム ^ 現フレーム
・押された瞬間 = XOR & 前フレーム
・離された瞬間 = XOR & 現フレーム
コード
コード(クリックで展開)
#include "DxLib.h"
#define KEY_CNT 256
//-----------------------------------------------------------------------------
char keybuf[KEY_CNT]; //キーバッファ (現フレーム)
char keybuf_old[KEY_CNT]; //1つ前のキーバッファ(前フレーム)
char key_down[KEY_CNT]; //押された瞬間
char key_up[KEY_CNT]; //離された瞬間
//-----------------------------------------------------------------------------
void Update_Key(void) //キーの入力状態
{
for(i = 0; i < KEY_CNT; i++)
{ keybuf_old[i] = keybuf[i]; } //1つ前のキーの状態を保存
GetHitKeyStateAll(keybuf); //全てのキーの状態を取得
for(i = 0; i < KEY_CNT; i++)
{
int key_xor = keybuf[i] ^ keybuf_old[i]; //前フレームと現フレームのxor
key_down[i] = key_xor & keybuf[i]; //押された瞬間 = (現フレームとkey_xorのAND)
key_up[i] = key_xor & keybuf_old[i]; //離された瞬間 = (前フレームとkey_xorのAND)
}
}
キーを指定する際は、DxLibのキーのコードを配列の[]内に記載してください。
(例: ESCが押された瞬間にbreak → if(key_down[KEY_INPUT_ESC]) {break;} )
キーコードについてはこちらをどうぞ
DxLibのキーコード一覧
以下は呼び出し側のコードです
#include "main.h"
#include "key.h"
/*
略
*/
while()
{
Update_Key();
/*
略
*/
//escが押されたら終了
if(key_down[KEY_INPUT_ESC]) { break; }
}
さいごに
最後まで読んで下さり、ありがとうございます。
自分自身が考えたものではなく、学校で教わったものなのですが、便利だと思ったので記事にしました。
DxLibの関数の部分を自分で記述すれば、他の言語でも併用できるかもです。
コードの書き方など、ご指摘がありましたら、ぜひコメントでお願いします!