マガジン

ボタンを一つも置かないゲーム:画面のどこを触っても反応する設計

遊びをつくる

執筆にClaudeを使用しています。

週末の明るい机に置かれた、一つの仕組みで遊べる小さな完成済みゲーム。
記事のテーマをもとに制作したAI生成の写真風イメージ。

ボタンを置かないゲームは、画面のどこを触っても反応します。ボタンがなければ押し間違えも起きない、と考えたくなりますが、本当にそうでしょうか。持ち替えた親指が端に触れただけで反応するかもしれませんし、ボタンがないせいで「ここを触ればよい」が伝わらないかもしれません。 この記事で確かめるのは、「画面全体を入力にした設計は、ボタンのある設計より誤操作が少ないのか、多いのか」です。結果は書きません。同じ小さなゲームを二つの条件で動かし、入力を一つずつ記録して、誤操作を数える手順を示します。読み終えたら、そのまま自分のゲームで測れます。 先に難しい点を挙げておきます。ボタンがないゲームでは、「誤タップ」の定義が変わります。ボタンなら「押すつもりのない場所を押した」で済みますが、全面入力では、触れたすべての場所が「正しい場所」です。そのため、入力が正しかったかどうかは座標では決まらず、本人の意図でしか決まりません。実験の中心は、この意図を後から確かめる仕組みを作ることです。

この記事の目次
  1. 問いを三つの数に分ける
  2. 二つの条件を同じゲームで作る
  3. 記録の取り方:ログと「意図の確認」を組み合わせる
  4. 結果の読み方:先に判断を決めておく
  5. 起こりやすい誤り
  6. 次の行動

問いを三つの数に分ける

「誤操作」を一つの言葉のまま扱うと、数えるときに迷います。次の三種類に分けて数えます。

  • 意図しない反応、内容:触れたつもりがないのにゲームが反応した、主に起きる条件:全面入力
  • 反応しなかった意図入力、内容:操作したのに何も起きなかった、主に起きる条件:ボタンあり
  • 取り違え、内容:タップのつもりが別の入力として扱われた、主に起きる条件:両方

ボタンあり条件で、ボタンの外を触って無反応だった入力は、意図があったかどうかで二つに分かれます。探してもボタンが見つからずに触った入力は、二行目に数えます。ボタンの周りを指がかすめただけなら、誤操作とは数えません。

指標は次の三つに絞ります。

  • 総入力数(反応したものと無反応だったものの合計)
  • 意図しない入力の割合(意図しない入力数 ÷ 総入力数)
  • 意図したのに反応しなかった入力数

意図しない入力は、数ではなく割合で見ます。よく触る人ほど絶対数が増えるためです。ただし総入力数が少ないと割合は大きく揺れます。割合の横には必ず分母を並べて読みます。

二つの条件を同じゲームで作る

比較する条件は二つだけです。

  • 全面条件:画面のどこを触っても、玉が上に跳ねます。
  • ボタン条件:画面下の色のついた帯の中だけが反応します。帯の外を触っても何も起きません。

条件以外は完全に同じにします。玉は重力で落ち、画面中央の帯(高さ40〜60%)の中に何秒とどまれたかを補助指標として出します。この補助指標は、ゲームとして成り立っているかを確かめる目安です。比較の主役にはしません。

次のコードは、一つのHTMLで両方の条件を動かします。URLの末尾に ?mode=zone を付けるとボタン条件、付けなければ全面条件です。ボタン条件の「ボタン」は、見た目だけの色帯で、HTMLのボタン要素ではありません。30秒たつとゲームが止まり、全入力のログが画面に出ます。

html
<!doctype html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
html,body{margin:0;height:100%;overflow:hidden;background:#123;touch-action:none;user-select:none}
#band{position:fixed;left:0;right:0;top:40%;height:20%;background:#2a4a5a}
#ball{position:fixed;left:calc(50% - 16px);width:32px;height:32px;border-radius:50%;background:#fd6}
#zone{position:fixed;left:0;right:0;bottom:0;height:20%;background:#c63;display:none}
#log{position:fixed;left:8px;top:8px;right:8px;color:#9cb;font:12px monospace;word-break:break-all}
</style>
<div id="band"></div><div id="zone"></div><div id="ball"></div><div id="log"></div>
<script>
const mode=new URLSearchParams(location.search).get('mode')||'full';
const ball=document.getElementById('ball'),out=document.getElementById('log');
if(mode==='zone')document.getElementById('zone').style.display='block';
let y=innerHeight*0.5,v=0,t0=performance.now(),inBand=0,last=t0,log=[],over=false;
function rec(e,k){log.push([Math.round(performance.now()-t0),Math.round(e.clientX),Math.round(e.clientY),k]);}
addEventListener('pointerdown',e=>{
  if(over)return;
  if(!e.isPrimary){rec(e,'multi');return;}
  if(mode==='zone'&&e.clientY<innerHeight*0.8){rec(e,'outside');return;}
  v=-6;rec(e,'jump');
});
addEventListener('pointercancel',e=>rec(e,'cancel'));
function tick(now){
  if(over)return;
  const dt=now-last;last=now;
  v+=0.25;y=Math.min(innerHeight-32,Math.max(0,y+v));
  const b=y+16;if(b>innerHeight*0.4&&b<innerHeight*0.6)inBand+=dt;
  ball.style.top=y+'px';
  if(now-t0>=30000){over=true;out.textContent='帯の中 '+Math.round(inBand/1000)+'秒 '+JSON.stringify(log);return;}
  requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
</script>

ログの各行は [開始からのミリ秒, x座標, y座標, 種別] です。種別は四つあります。

  • jump:反応した入力です。
  • outside:ボタン条件で、帯の外を触って無反応だった入力です。
  • multi:二本目以降の指です。反応させず、記録だけ残します。
  • cancel:ブラウザや端末が操作を取り消したときに記録されます。

touch-action:none を指定しているため、このページではピンチ拡大や二度押しの拡大が起きません。実際のゲームでこの指定を外すと、誤操作の性質が変わる点は、後の節で扱います。

なお、アソバースではゲームがsandbox付きのiframeで動くため、「画面全体」とはゲームが表示されている枠の中を指します。投稿を考えているなら、この枠の中で測るのが実際の遊ばれ方に近くなります。

記録の取り方:ログと「意図の確認」を組み合わせる

自動ログは、いつ・どこを触ったかを教えてくれますが、意図は教えてくれません。意図は、プレイ後に本人へ確かめます。

準備するもの

  • 上のHTMLを開ける端末(普段遊ぶ人が使う端末にします。複数あるとさらによいです)
  • 画面録画(任意です。あれば、意図の確認が正確になります)
  • 記録用の表(紙でも表計算でも構いません)

録画する場合は、協力者に目的と保存の扱いを説明し、同意を得てください。顔や周囲が映らない範囲にとどめます。

手順

  1. 協力者を3〜5人集めます。ゲームを作る人が多い集まりなら、遊ぶ側の経験が少ない人も混ぜると、差が見えやすくなります。
  2. 最初の1回は条件を問わず練習として捨てます。操作を学ぶ時間が結果に混ざるのを防ぐためです。
  3. 全面条件を3回、ボタン条件を3回、それぞれ30秒で遊んでもらいます。
  4. 順番は人によって入れ替えます。ある人は全面から、次の人はボタンから始めます。慣れの影響を打ち消すためです。
  5. 1回ごとに、画面に出たログを丸ごと写し取ります(文字で保存するか、スクリーンショットで残します)。
  6. 全員が遊び終えた後で、ログの行を一つずつ読み上げ、「この入力は触るつもりでしたか」と聞きます。時刻だけでは思い出せないときは、録画を見ながら確認します。

記録表の例

1行が1回の入力です。

協力者 / 条件 / 回 / 時刻(ms) / x / y / 種別 / 意図あり(○/×)

意図の確認は、ゲームの直後に行ってください。日をまたぐと、本人の記憶があいまいになります。遊んでいる最中に「今のは違う」と声に出してもらう方法もありますが、声を出すこと自体が操作に影響します。基本は後から確認する形にします。

結果の読み方:先に判断を決めておく

数字が出てから基準を決めると、都合のよい読み方になりがちです。遊ぶ前に、次のような判断の分かれ目を書いておきます。

全面条件で、意図しない入力の割合がボタン条件より高かった場合

まず、意図しない入力のx座標とy座標を見ます。

  • 画面の左右の端や下端に偏っている:持ち替えや、手の付け根の接触が疑われます。端に反応しない余白を設ける案が考えられます。
  • 画面全体に散らばっている:持ち方の問題ではなく、「触れた瞬間に反応する」仕様が原因かもしれません。指を離したときに反応させる、少し押し続けたときだけ反応させる、といった案を試す価値があります。
  • 特定の時刻に固まっている:ゲーム側の演出(急に画面が変わる、など)に反応して、慌てて触っている可能性があります。

ボタン条件で、「意図したのに反応しなかった入力」が多かった場合

outside の行のうち、意図ありと答えられたものを数えます。多ければ、ボタンの位置や大きさ、色が伝わっていません。全面条件の利点(探さなくてよい)が効いている可能性があります。

二つの条件で差が小さかった場合

人数も回数も少ない実験なので、差がないとは断言できません。ただし、少なくとも「全面入力にしたことで極端に悪化する設計ではなさそうだ」という判断材料にはなります。続ける場合は、人数を増やすか、ゲームの種類を変えて再度測ります。

補助指標(帯の中の秒数)の読み方

秒数が条件で大きく違うなら、誤操作ではなく、操作のしやすさそのものが違っています。その場合は、誤操作の割合だけで優劣を決めず、「うまく遊べたか」も一緒に報告してください。

どの結果になっても、読むのは条件ごとの割合と分母の組です。例えば「3人で、各条件の総入力が少ししかない」なら、割合は参考程度にとどめます。

起こりやすい誤り

意図の確認を後付けで誘導してしまう

「これは間違いですよね」と聞くと、本人は同意しがちです。「このとき、触るつもりでしたか」と、中立な言い方で聞きます。聞く順番も、時刻順にしてください。

練習不足のまま測る

最初の数十秒は、操作の理解に使われます。練習を捨てても、1人目の最初の本番だけは慣れが残ります。順序を入れ替える理由はここにもあります。

ボタン条件の帯が目立ちすぎる、または目立たなすぎる

色や大きさで、結果は大きく変わります。比較したいのは「ボタンの有無」であって、「ボタンのデザインの良し悪し」ではありません。公開前に、別の人に「どこを触ればよいと思いますか」と聞いて確認すると、帯の見つけやすさが極端でないかを点検できます。

端末とブラウザの違い

OSの端のジェスチャ(戻る、ホームなど)と競合して、cancel が増えることがあります。端末が違う協力者の結果を一つにまとめず、端末ごとに分けて読みます。

touch-action を外したときの比較

上のコードでは、ピンチや二度押しの拡大を止めています。実際のゲームでこの指定を外すと、拡大やスクロールがゲームの入力と競合し、cancel が増える可能性があります。この記事の実験は、あくまで拡大を止めた場合の比較です。

分母を見ずに割合だけで語る

総入力が10回と100回では、同じ10%でも重みが違います。表には必ず総入力数を併記します。

「ボタンなし」の利点を誤操作だけで判断する

全面入力には、画面が小さい端末で押しやすい、初見でも迷わない、といった別の利点があるかもしれません。ここで測るのは誤操作という一面だけです。

次の行動

まず上のコードをHTMLファイルとして保存し、自分で全面条件とボタン条件を一回ずつ30秒遊んで、ログの形を確かめてください。次に、協力者を2〜3人集めて、手順の通りに記録を取ります。自分のゲームに合う入力の取り方が見えてきたら、index.html として単独で動く形に整えて、アソバースへ投稿してみてください。