2017年1月9日月曜日

バーチャルパッドのボタンをUIButton/ButtonでやるのはNG

スマホのバーチャルパッドって操作し難いですね。
知ってたことですが。
改善の余地が色々あって楽しい箇所ではあります。

前々回の記事でファミコンのA/Bボタンの配置について触れましたが、今回はその中身の実装について触れます。
最初、上記のA/Bボタンをそれぞれ UIButton(AndroidならButton)クラスを使って実装したのですが、それだと実際のところかなり操作し難いです。

どうすれば、改善できるだろうか?
まず、昔実機でファミコンをプレイしていた時に、どうやってコントローラを操作していたのか思い出してみることにしました。
そして、スーパーマリオで「Bダッシュをしながらジャンプ」をする時、親指の先でBボタンをホールドした状態で少し右(Aボタン寄り)にスライドして親指の腹でAボタンを圧迫することでジャンプしていた事を思い出しました。

これはiOSやAndroidの標準のボタンでは処理できない操作です。
何故なら、Bボタンをタッチしたイベントは、Aボタンの方でスライドしてもBボタンのイベントとして処理されてしまうので。

そこで、ボタンをUIButtonからタッチ判定の無いUIImageViewに変更して、その上にA/Bボタン両方を覆いかぶせるようにUIViewを配置し、そのUIViewでタッチイベントを処理するようにしてみました。

変更時のcommit
①タッチ判定の変更
②中央付近で両方のボタンを押せるように修正

タッチエリアのイメージは下図のような形です。
処理的には、
・タッチ位置がタッチエリア外ならA/B両方OFF
・タッチ位置が重なるボタンをON
・タッチ位置が中央付近(※若干の遊び領域あり)ならA/B両方ON
という形。

このようにしてみたところ、バーチャルパッドでも「スーパーマリオでBダッシュしながらジャンプ」といった操作ができるようになりました。

スマホのバーチャルパッド自体が邪道だと思っていますが、それでも作るのであれば、可能な限り操作し易いものを作りたい。

ただし、ランドスケープのバーチャルパッド・・・お前はダメだ。

ゲーム画面にバーチャルパッドを重ねるという行為が許せません。
これは、ゲームコンテンツに対する冒涜だとすら思っています。
しかし、実際GooglePlayで公開されているエミュレータアプリのデザインを見てみると、そういう配置のものが多いこと...
そういう配置にせざるを得ないことは理解できますが、それでも何故、そんなクソみたいなデザインにしたのかと。

今回、一応ランドスケープでも動作できるように作っていますが、
このように、バーチャルパッドの無い美しいデザインにしてやりました。
現時点ではランドスケープでは何も操作できません。
観賞用ですね。
もちろん、将来的には外付けのキーボード or ジョイパッドで操作できるようにするつもりです。

ランドスケープの場合、キーボードやジョイパッド必須(持っていないならポートレイトでプレイしてね)って仕様にすべきだと思っています。

そうすれば、
・ユーザーは持っていなければポートレイトでプレイすれば良い
・開発者はクソみたいなバーチャルパッドのデザインを拒否できる
・外付けコントローラを売っているメーカーが潤う
という具合に、ユーザー・開発者だけでなく新たな第三者までもが得をするという素敵な形になります。

更に言うと、そもそもランドスケープだとスマホの画面をタッチ操作し難い(スマホはポートレイトで持つ前提だから縦長になっている)という構造的な問題もあるので、ランドスケープなら外部入力機器を使うべきというのは、すごく理に適ったデザインだと思うのです。