LoginSignup
2
1

DxLib キーが押された瞬間 / 離された瞬間 を取得する

Last updated at Posted at 2021-12-31

こんにちは。プログラミング初心者ですが、記事を書いてみようと思います。
これよりももっといい感じの方法があるかもです。その場合はご教示お願いします。


動作

input.gif
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)

●表にしたもの
input_state2.png

表の内容を詳しく説明します。

__前フレームと現フレームのXOR__で、__押された瞬間・離された瞬間__が分かります。
しかし、XORのみだと、押された瞬間・離された瞬間を区別できません
なので、
① __XORと前フレームのAND__で__押された瞬間__を求める。
② __XORと現フレームのAND__で__離された瞬間__を求める。



要点まとめ
・前フレームと現フレームの比較で押された瞬間・離された瞬間を求める ・比較はビット演算を使う

・押された瞬間 / 離された瞬間はXORを使って求める
・XORのみだと区別できないので、ANDを使ってそれぞれ求める

・押された瞬間・離された瞬間(XOR) = 前フレーム ^ 現フレーム
・押された瞬間 = XOR & 前フレーム
・離された瞬間 = XOR & 現フレーム


コード

コード(クリックで展開)
key.cpp
#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のキーコード一覧

以下は呼び出し側のコードです

main.cpp
#include "main.h"
#include "key.h"

/*
    略
*/

while()
{
    Update_Key();

    /*
        略
    */

    //escが押されたら終了
  if(key_down[KEY_INPUT_ESC]) { break; }
}

---

さいごに

最後まで読んで下さり、ありがとうございます。
自分自身が考えたものではなく、学校で教わったものなのですが、便利だと思ったので記事にしました。
DxLibの関数の部分を自分で記述すれば、他の言語でも併用できるかもです。

コードの書き方など、ご指摘がありましたら、ぜひコメントでお願いします!

2
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1