🦜

Go&Ebitengineでタッチ入力を考える

に公開

はじめに

Zennの記事への埋め込み記法で、埋め込み可能な一覧の中に「Zennの記事」というのが無いのはとても不思議に思う。URLを書けばいいんだけど、自分の記事一覧から表示したときのURLは果たして人が見るときのURLと一致しているのか確信が持てない。適当に貼ってみるが。
ともあれ前回書いた記事がこちらで、今回はこれの続きになる。
https://zenn.dev/mirichi/articles/9e9fc22b568187

Githubに置く

置いた。今回は挙動的には前回と変わらないので実行するページは確認用に作ってはあるけど省略。
コードはこちら。
https://github.com/mirichi/EbitenSampleTest/tree/main/002

これは何か

もともとマウス入力用に作っていて、Webにアップできるならスマホでも操作できるようにしたいと思い、試行錯誤したわけだが。
かなり雑な感じになってバグで苦労したので、このへんをもっとどうにかできないかと考えてみた。

内容

前回のコードはこのような感じになっていて、マウス用の処理にタッチ用の処理を強引に追加したような状態である。動いたからいいと言えばそれまでだが、今後何かを作るたびに試行錯誤するのもよろしくない。タッチ操作系でバグるとつらい。
https://github.com/mirichi/EbitenSampleTest/blob/main/001/main.go#L44-L91

そこで、マウスとタッチの操作系を統一してやれば、マウス操作で確認したものをそのままタッチで操作できるようになるのではと考えた訳だ。うちのPCの画面がタッチ対応なら問題はなかったかもだが。
マウスとタッチの入力は、なんとなく似ているように感じるが、そもそもプラットフォーム側からの入力がマウスイベントとタッチイベントで分かれているように、根本の部分で違うものとなっている。違いとしてはこんな感じか。

  • マウスはボタンを押していない間でもカーソル位置が取得できる
  • タッチはマルチタッチができる

こんなマウスとタッチを統合して扱うためには、それぞれの良いところを殺して最大公約数を取得する必要がある。すなわち、ボタンを押さないとカーソル位置は取得できず、シングルタッチ専用、という残念デバイスとして扱うことになる。
そうして統合してやれば、アプリ側では単一の残念デバイスとして考えることができて、このようなコードで入力を処理できるようになる。
https://github.com/mirichi/EbitenSampleTest/blob/main/002/main.go#L40-L66
タッチの処理はAPIがマルチタッチ対応になっているせいで煩雑になりがちだが、そこを排除できたのでだいぶすっきりした。
入力処理はinput.goに分けて書いてみた。こういった場合の関数名の付け方だとか、そういったあたりはGoの流儀がわかっていないのでイケてないことになっているかもしれない。そのうち勉強する。
https://github.com/mirichi/EbitenSampleTest/blob/main/002/input.go
どうでもいいが、main.goのUpdateメソッドの最初にある処理は、デスクトップで動かすとEscで終了できるようになるが、ブラウザで動かしているときにEscを押すと固まる。ブラウザを閉じるわけにもいかんしな。マウスで小さい×ボタン押すの面倒なんよ。

input.goについて

マウスとタッチの1つ目の状態を判定して、各関数で状態を返すような処理になっている。基本的にマウスとタッチは基本同居しないから雑な作りで、同時操作したら前回座標あたりがバグりそうな気がしている。うちではテストできないが。
Input_Update()はUpdateから呼んでもらう。inpututil内でやってるようにinternal/hookを使えばわざわざ呼ばなくてもよくなるのだが、internalに入ってることを考えるとユーザが使うべきではないのだろう。便利そうなのに。

おしまい

世の中にはブラウザで動作してスマホを意識したゲームなどもあるので、こういうことを考えてる人も多いのだろうと思う。ebitengine-inputとかでできそうな気がするし。

Discussion