入力の基本

■サンプル

●環境
	VisualStudio 2017

	DirectX9(June 2010)

●リンク
	サンプル

■概要

入力処理はゲームで必ず用意する必要がある処理の1つです。
入力は入力デバイスが「押された」「押されてない」の判断をします。

●入力デバイス
	入力は外部の入力デバイスの情報を取得します。
	対象となるデバイスでよく使用するのは「ゲームパッド」「キーボード」
	「マウス」「液晶(スマホ)」などです。

	gmpg_0210

	これらのデバイスから入力された、されていないという情報を取得します。

●必須処理
	入力処理の中でも最低限ライブラリ(ゲームエンジン)に必要な処理として
	次の3つの処理があげられます。

		「キーを押した瞬間の判定」
		「キーを押しているか否かの判定」
		「キーを離した瞬間の判定」

	その他にゲームパッドでアナログスティックを使用する場合は
	スティックを倒した角度を取得する必要があったりと、
	各デバイスによって取得処理が増えることがあります。
	※今回の説明やサンプルはキーボードの入力取得で行っています。

●入力情報取得方法
	ゲームを作成する場合に入力デバイスから入力されたかどうかを取得する方法として
	DirectInputやXInputなどのゲームライブラリが提供してくれている機能を使って取得します。
	しかし、これらのライブラリのサポートは「どのキー(ボタン)が押されたか否か」しか
	判断してくれないことが多いです。
	なので、「キーを押しているか否かの判定」という処理は簡単にできますが、
	その他の「キーを押した瞬間の判定」や「キーを離した瞬間の判定」は自分で実装します。

■準備

今回のサンプルを含めた入力の説明は最も簡単とされている方法で実装します。
それは各キーの状態を保存しておくという方法です。
状態は「押されていない」「押された瞬間」「押されてる」「離された瞬間」の4種類を用意します。

	gmpg_0211

●状態定義
	状態の定数はdefineやconstではなく、enumで定義されてることが多いです。

	・例
		enum INPUT_STATE
		{
			NOT_PUSH,	// 押されてない
			PUSH_ENTER,	// 押された瞬間
			PUSH,		// 押されてる
			PUSH_EXIT,	// 離された瞬間
		};

●キーの割り当て
	ゲームで使用するキーは仕様で決まっています。
	決まっているキーを各ライブラリのキー情報に割り当てておくと処理がやりやすくなります。

	・例
		// キー情報
		enum KEY_INFO
		{
			UP_KEY,
			DOWN_KEY,
			LEFT_KEY,
			RIHGT_KEY,
			MAX_KEY_INFO,
		};

		// キー情報配列
		// 定数はDirectInputで用意されているDIK_~を使用する
		int g_KeyInfo[] =
		{
			DIK_UP,
			DIK_DOWN,
			DIK_LEFT,
			DIK_RIGHT,
		};

●キー状態を保存する変数の配列を用意
	キー状態の宣言とキーの割り当てが終わったら、この二つの情報を使用して、
	キー状態変数の配列を用意します。
	この配列の状態を毎フレーム変更することでキーの状態を確認できるようにします。

	・例
		// キー状態定数とキー情報の宣言は終わっているとする
		// キーの入力状態を保存する配列
		INPUT_STATE g_InputState[KEY_INFO::MAX_KEY_INFO];

■状態の更新

DirectInputなどのライブラリでは毎フレーム、キーボードなどのデバイスの情報を取得します。
この取得した情報を現在の状態と照らし合わせて状態を更新します。

gmpg_0212

■キーを押した瞬間状態

「キーを押した瞬間」状態に設定する条件は以下の通りです。

●条件
	・該当するキーの状態が「押されていない」状態で
	 「そのフレームにキーが押された」

	・該当するキーの状態が「離された瞬間」状態で
	 「そのフレームにキーが押された」

	gmpg_0213

■キーを押している状態

「キーを押している」状態に設定する条件は以下の通りです。

●条件
	・該当するキーの状態が「キーを押している」状態で
	 「そのフレームでもキーが押されている」

	・該当するキーの状態が「キーを押した瞬間」状態で
	 「そのフレームでもキーが押されている」

	gmpg_0214

■キーを離した瞬間状態

「キーを離した瞬間の判定」状態に設定する条件は以下の通りです。

●条件
	・該当するキーの状態が「キーを押している」状態で
	 「そのフレームでキーが押されていない」

	・該当するキーの状態が「キーを押した瞬間」状態で
	 「そのフレームでもキーが押されていない」

	gmpg_0215

■押していない状態

押していない状態にする条件は上で書いている条件に当てはまらない場合の
全てとなるので条件分岐で「else」を用意し、状態を「押されていない状態」に変更します。

●条件
	押されていない状態にする条件は一応書いておきます。
	
	・該当するキーが「離された瞬間状態」で
	 「そのフレームでもキーが押されていない」

	gmpg_0216

■判定処理

各状態の判定処理は簡単で、各状態を判定する関数を用意します。
この関数の引数に判定したいキーを指定し、関数内で状態の値をチェックして
判定したい状態(押された瞬間、押されている等)だったらtrue、そうではなかったらfalseを返します。

●例
	// 押した瞬間かどうかの判定関数
	bool GetKeyEnter(KEY_INFO key_info)
	{
		// 指定されたキーの状態が押された瞬間ならtrue
		return (g_InputState[key_info] == INPUT_STATE::PUSH_ENTER);
	}

	// 押されてるかどうかの判定関数
	bool GetKey(KEY_INFO key_info)
	{
		// 指定されたキーの状態が押されてるならtrue
		return (g_InputState[key_info] == INPUT_STATE::PUSH);
	}

	// 話した瞬間かどうかの判定関数
	bool GetKeyExit(KEY_INFO key_info)
	{
		// 指定されたキーの状態が離した瞬間ならtrue
		return (g_InputState[key_info] == INPUT_STATE::PUSH_EXIT);
	}