【Defold】キーボードやマウスの入力を検知する

# はじめに
この記事では、キーボードなどの入力を検知する基本を紹介します。
Defoldでゲームを作ろうとしている人にとっては、めちゃくちゃ重要です。

# 流れ
マウスの入力やキーボードの入力のことをインプットといいます。
最初にインプットを処理する流れを紹介します。図にするとこんな感じです。

![flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/7bb932d3-7e2c-b1d2-2a58-8a1d4b949093.png)
**"aquire_input_focus"**の設定がされたゲームオブジェクトは、紐付いているスクリプトから入力を検知することができます。

また今回は、「←」や「→」を押すことで、前回作成したピンクの丸が動くようにしたいと思います。

# aquire_input_focusとは
ではさっそく、専門用語っぽいものが出てきました。ゲームオブジェクトが入力情報を参照できるようにする設定です。
"aquire"というのが「得る」という意味の英単語です。"input_focus"は名前から想像がつく人もいると思いますが、入力情報を知るために必要なものです。"input_focus"というチケットのようなものがあって、それを持っている人のみが、キーボードやマウスなどの入力情報を教えてもらえる権利があります。

そのチケットは複数のゲームオブジェクトに設定でき、それぞれのオブジェクトで同じ情報をゲットすることができます。ただ、チケットの最大数は16枚なので、17個目のオブジェクトで入力情報をゲットするには工夫が必要です。
簡単なのは、誰かからチケットを取り上げて、新しい人にあげることです。

ちなみに、"input_focus"を外すには "release_input_focus"の設定をしてあげます。

# 入力するキーの設定
マウスやキーボードから検知したいキーはこのファイルから設定します。
![2021-04-24_13h13_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/e7ad537c-97e9-fe08-6c5d-6c3c5233b696.png)
色々ありまますが、主に使うのは、キーボードの**Key Triggers**とマウスの**Mouse Triggers**です。

まぁ習うより慣れろということで、やってみましょう。
今回入力したいのは「←」と「→」なので、**Key Triggers**の所の「＋」マークを押して、Inputを「Left」と「Right」をそれぞれ設定します。
![2021-04-24_13h18_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/51401bfc-6909-6a19-404b-5b976d0213f4.png)

次に設定するのが"Action"です。個々に設定した名前はコードで使うのでわかりやすいものにしてください。
![2021-04-24_13h21_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/18772d33-d8f6-e464-6e5f-0084527798e7.png)

マウスの入力は今回は使わないので「-」を押して消しておきましょう。
![2021-04-29_13h50_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/b74504f7-9308-7d75-e8c0-194a1b94b08a.png)


これで、入力の下準備は終了です。Defoldではここで入力したキー情報にしかアクセスすることができません。

# input_focusを設定する。
そしたら、前回までで使っていたScriptファイルのinit関数のところに
`msg.post(".", "aquire_input_focus")`と入力することでinput_focusを設定することができます。例えて言うと、チケットをこのゲームオブジェクト渡すことができます。

msgは今度記述しますが、手紙みたいな物です。メッセージです。宛先が"."、件名が"aquire_inpit_focus"です。「.」というのは、自分宛てっていう意味です。

とりあえず、"aquire_input_focus"のメッセージを自分宛てに送ることで、そのオブジェクトは入力情報の閲覧チケットを入手することができます。

# on_input
チケットを入手をしたゲームオブジェクトは、設定したキーが押されたときに、**on_input**が実行されます。
↑で設定した **"action"**っていうのは、ここで使います。
![2021-04-24_13h21_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/18772d33-d8f6-e464-6e5f-0084527798e7.png)

試しに on_input の中に `print("test")` を入力して、実行してみましょう。
そうするとコンソールに**test**が表示されます。左側にある数字は、その文字列が何回表示されたかを示しています。
例えば下の画像だと、**test**という文字列が、221回表示されたことを示しています。
![2021-04-29_13h53_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/af1b791e-0435-3b40-ff55-93c568b52cce.png)
この数字が「→」や「←」を押しているときに増えれば、入力はうまく行っています。

# どのキーが押されたかを知る
いままでは、「→」が押されても、「←」が押されても、区別していませんでした。
でも本当は、それぞれ別の処理をしたいです。

ではどうなっているかを確認してみましょう。さっきの**test**を以下のように変更してみましょう。

```lua
function on_input(self, action_id, action)
	print(action_id)
end
```

そうすると、「→」を押しているときと、「←」を押しているときに違う表示が出ると思います。
![2021-04-29_14h00_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/4c0ee26f-610f-7e2b-6510-0aa55c8971fb.png)

この **move_right** や **move_left** は上のActionで設定したやつです。
hashって書いてあるのは、詳しくは知らなくていいのですが、**on_input**で、**action_id** はhash値になっています。
よくわからないと思いますが、実際にやってみればなんとなくわかると思います。

```lua
function on_input(self, action_id, action)
	if action_id == hash("move_right") then
		print("right")
	elseif action_id == hash("move_left") then
		print("left")
	end
end
```

とりあえずこれで、「→」を押すと **"right"** 、「←」をおすと **"left"** と表示されます。
![2021-04-29_14h09_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620977/f315b678-82ab-e624-9154-99597e54d3e0.png)

 **hashにしないと絶対に動かないので、動かないときはまず確認してください。**


# 押した瞬間・離した瞬間
いままでは、押している間にずっと実行されていましたが、**押されたときに1回だけ** 実行したいと思います。

どうやってやるのかって言うと、今まで使っていない **action** を使います。
action はテーブルになっていて、以下のようになっています。

|key|変数型|
|:-:|:-:|
|pressed| true / false |
|repeated| true / false |
|released| true / false |
|value|数字|

**pressed** ・・・ 押された瞬間に1回だけ true になります。
**repeated** ・・・ よくわからんけど、長押ししてると定期的に true になりまｍす。
**released** ・・・ 離した瞬間に1回だけ true になります。
**value** ・・・ 押しているときは 1、 離しているときは 0 です。

これらの値はプリントで見ることもできます。→ `print(action.pressed)` 

では押された瞬間に1回だけ "right"とか、"left"とかを表示してみようと思います。

```lua
function on_input(self, action_id, action)
	if action.pressed and action_id == hash("move_right") then
		print("right")
	elseif action.pressed and action_id == hash("move_left") then
		print("left")
	end
end
```
(本当は、もっと簡単にできるのですが、わかりやすいように非効率に書いています)


# さいごに
キー入力の紹介でした。
何度もいいますが、**hashを忘れないようにしてください！**

[目次](https://qiita.com/nonzu/items/73a39368855f3e1e0f28)