Go&Ebitengineでボタンを作ってみる
はじめに
そういえばタッチ用のGUIって作ったことがないなと思い、とりあえず手っ取り早くボタンを作ってみた。先に感想を述べると、マウスとは違うなって思いました(小並感)。
こちらの記事でEbitengineを使ったマルチタッチサンプルを作ってからの続きとなる。
Githubに置く
動かすのはこちら。
コードはこちら ui.goが増えた。そういえばGoではよくディレクトリを分けてソースを管理するみたいだがそのへんはまだよくわかっていない。変数とか関数も頭大文字で公開らしいが公開範囲とかよくわかっていない。つまりパッケージという概念がよくわかっていない。いろいろ勉強中。これは何か
ボタンUIの構造体Buttonを新規に作成して、シンプルなボタンを追加してみた。四角を増やすことができるので衝突判定のロジックを見直した。あとは細かいバグを修正したり。
内容
タッチ入力はマウスと違って、タッチ中しか座標が取得できない。ボタンというGUIは、手元でGoogleのアプリを少しいじってみた感じでは、
- タッチ開始がボタンの位置であればタッチ開始
- スライドしてボタンの範囲から出たら終了、スライドしてボタン上に戻しても再び開始はしない
- ボタン外でタッチしてからボタン上にスライドしても開始したことにならない
- タッチ開始後にボタン上で離すと、ボタンをタップしたことになる
みたいな挙動をしていたので、それに合わせて作ってみた。いや、厳密にはボタンが小さすぎてよくわからんかったのだが…。このへんはGUI設計のガイドライン的なものがありそうな気がするし、ゲーム用であればゲームに合わせて気持ち良く操作できるようにするものだろうか。
ともあれ、タッチ操作で厄介な点は「タッチ中しか座標が取得できない」ところで、つまり、指を離した瞬間に離したことを判定できるが、そのタイミングではもう座標が取れない。これはマウス操作では存在しなかった問題である。Ebitenではinpututil.IsTouchJustReleased(id)で指を離したことをチェックして、そのままinpututil.TouchPositionInPreviousTick(id)で前回座標が取得できる。なるほど実によく考えられている。サンプルが完成した後に気付いたので今回は使ってない。
コードについて
追加したui.goはこうなっている。Rectと似たようなもんだが、main.goのほうでタッチしたことを認識したらPress()を呼んでタッチ情報を保存、Updateでその後の操作を追跡するようになっている。
controlインターフェースは今後コントロールの種類を追加したときにうまく動くかどうかわからないが、土台として作っておいた。うまくいかんかったら修正していくことになる。
main.goのほうはGame構造体にcontrolインターフェースのスライスを追加して、
初期化にcontrolsに入れるボタンの生成を追加。
Updateメソッドの後半にUI関連処理を追加した感じである。
追加したボタンが四角を増やしたり減らしたりだったので、衝突判定も全体に対して処理できるように修正しておいた。
おしまい
タッチ独特の挙動のせいでバグって悩んで1時間ほど寝るのが遅くなった。この経験が将来生きてくるのではないかと信じたい。
せっかくUI周りを作り始めたのだし、他にも作ってみたいものはあるので、チャレンジしてみたいと思う。
Discussion