「指についてこない」の正体は、重さではなかった
制作ノート / ぷちけんちくのタッチ操作改善
- 「指についてこない」という指摘
- 最初に疑ったのは処理の重さ
- 実測して分かった本当の原因
- ブラウザは指の動きを間引いて伝えてくる
- 直し方:点ではなく線で拾う
- 結果:1マスから5マスへ
- ついでに直した長押しの問題
- まとめ
「指についてこない」という指摘
ぷちけんちくは、同じ絵のタイルを指でなぞってつなげ、消していく60秒のパズルです。 公開してしばらくして、遊んでくれた人から短い指摘をもらいました。
「速くなぞると、指についてこない」
自分でもスマホで試してみると、確かにそうでした。 ゆっくりなぞれば問題ないのに、急いでなぞると途中のタイルが飛ばされて、線が途切れるのです。 パズルゲームで「速く操作すると失敗する」のは致命的です。急いでいるときこそ気持ちよく動いてほしい。
最初に疑ったのは処理の重さ
こういう症状を聞くと、まず「処理が重くて追いつけていないのだろう」と考えます。私もそうしました。 画面の描画を軽くする、計算を減らす、という方向で手を入れるつもりでした。
ただ、その前に一度きちんと測っておくことにしました。 本当に重いのなら、指を動かしている間の処理時間が長くなっているはずです。 逆に言えば、測れば思い込みかどうかがはっきりします。
実測して分かった本当の原因
計測してみると、処理時間はまったく問題ありませんでした。1回あたりの処理は一瞬で終わっている。 重さが原因ではなかったのです。
では何が起きているのか。指を動かしたときに来る通知そのものを記録してみたところ、原因がはっきりしました。 速くなぞったとき、ブラウザから届く「指の位置」の数が、明らかに足りないのです。
ブラウザは指の動きを間引いて伝えてくる
スマートフォンのブラウザは、指が動いた軌跡をすべては教えてくれません。 一定の間隔でサンプリングして、間引いた位置だけを通知してきます。 画面のリフレッシュに合わせて、おおむね1秒に60回程度です。
ゆっくりなぞっているときは、この間隔でも十分に細かく拾えます。 ところが指を速く動かすと、1回の通知の間に指が何マスも進んでしまう。 私のコードは「通知が来た位置のマス」だけを拾っていたので、 間を飛ばされたマスは、指が実際には通っているのに存在しなかったことにされていました。
つまり、これは処理速度の問題ではなく取りこぼしの問題でした。 いくら処理を軽くしても、そもそも通知が来ていないマスは拾えません。 最初の見立てのまま描画の最適化を進めていたら、時間を使って何も改善しないところでした。
直し方:点ではなく線で拾う
直し方は、原因が分かってしまえば単純でした。 「今回の位置」だけを見るのをやめて、「前回の位置から今回の位置までの線」を見るようにしたのです。
前回の指の位置と今回の指の位置を線で結び、その線が横切ったマスをすべて拾う。 こうすれば、ブラウザが間引いていても、指が通ったマスは漏れなく拾えます。
考え方としては、点をつなぐのではなく軌跡をなぞり直しているイメージです。 間引かれた分は、こちら側で補ってやればいい。
結果:1マスから5マスへ
修正の効果を確かめるため、同じ速さで素早くなぞったときに拾えるマスの数を測りました。
| 修正前 | 1回の通知につき 1マス しか拾えない |
|---|---|
| 修正後 | 同じ動きで 最大5マス 拾える |
体感でも、指の動きにぴったりついてくるようになりました。 同じ問題は、指でなぞる操作を使うズメンにも当てはまったので、そちらにも同じ直し方を入れています。
ついでに直した長押しの問題
タッチまわりを見直したとき、もうひとつ別の問題も見つかりました。 ヤネランは落下中に長押しすると傘を開いて滑空できるのですが、 スマホで長押しすると「コピー」のメニューや文字選択が出てしまい、傘が使えない状態でした。
これはブラウザの標準動作なので、明示的に止める必要があります。対策は4点セットでした。
- ページ全体で文字選択と長押しメニューを無効にする
- ゲームを描いている領域でも同じ設定にし、ドラッグも無効にする
- 操作エリアで、右クリックメニュー・選択開始・ドラッグ開始の動作を打ち消す
- 指を触れた・動かしたときの標準動作(画面スクロール等)を打ち消す
ここで一度やらかしたのが、文字選択の禁止をページ全体にかけすぎて、ランキングの名前が入力できなくなったことです。 入力欄だけは選択できる状態に戻す必要がありました。 また、右クリックメニューの抑止も、ページ全体にかけるとフッターのリンクなどが不便になるため、 操作エリアだけに限定しています。
まとめ
- 「反応が悪い」の原因は、処理の重さとは限らない
- スマホのブラウザは、指の動きを間引いて通知してくる
- 速い動きに追従させたいなら、点ではなく前回位置からの線で拾う
- 手を入れる前に一度測る。測らずに最適化すると、見当違いの場所を直すことになる
- タッチの標準動作を止めるときは、入力欄など止めてはいけない場所に注意する
「なんとなく反応が悪い」で終わらせず、実際に何が届いているかを見にいったのが分かれ目でした。
実際になぞってみる
改善後の操作感は、実際に触ってみるのが早いと思います。60秒だけです。