AI で作ったゲームがスマホで動かないときの直し方:タップ・画面の大きさ・スクロール・音
要約
パソコンで動く AI のゲームがスマホで動かないときは、症状から原因を確かめます。矢印キーにしか反応しない、タップした場所とずれる、指を動かすと画面がスクロールする、音が出ない、のどれかが多くあります。キーボードの操作は残したまま、タップのボタン、座標の換算、キャンバスだけの touch-action、スタートボタンを押してからの音の開始を足し、直したファイルを自分のスマホで開いて確かめます。
Free プラン: カード登録なし、公開 1 ページまで
目次
パソコンでは遊べたゲームを、スマホで開くと動かせない。AI に作ってもらったブラウザゲームで、よく起きることです。矢印キーにしか反応しない、タップした場所と違うところが反応する、指を動かすと画面ごとスクロールする、音が鳴らない。多くは、スマホの指の操作を受け取る作りが足りないだけで、ゲームを作り直さなくても直せます。
このページは、症状から原因を見分ける表、原因ごとの確かめ方と AI への頼み方、そのまま貼れる短いコード、直したあとにスマホで確かめる手順の順に説明します。どの直し方も、パソコンの矢印キーとマウスの操作を残します。まだゲームを公開していなくて、友だちに送れるリンクの作り方から知りたいときは、ガイド ChatGPT・Claude・Gemini で作ったゲームを、友だちがログインなしでスマホで遊べるように公開する を先に読んでください。
症状から原因を見分ける
ゲームのコードを AI の画面かテキストエディターで開き、表の「確かめること」にある言葉を検索します。
| スマホでの症状 | 確かめること | 直し方 |
|---|---|---|
| ゲームは始まるが、キャラクターを動かせない | keydown や ArrowLeft はあるのに、pointerdown も touchstart もない | タップのボタンを足す |
| タップした場所と、違うところが反応する | 指の位置(clientX、offsetX)をそのまま座標に使っている。キャンバスを CSS で縮めている | キャンバスの座標を換算する |
| 画面全体が小さい、または横や下にはみ出す | <meta name="viewport" の行がない。高さに 100vh を使っている | 画面の大きさに合わせる |
| 指でなぞると画面がスクロールする、拡大される | キャンバスに touch-action がない。document の touchmove で preventDefault() を呼んでいる | 指の動きをゲームに渡す |
| ボタンから指を離しても、キャラクターが動き続ける | pointercancel を受け取っていない | 指の動きをゲームに渡す |
| 音が出ない | ページを開いたときに new AudioContext() や play() を呼んでいる。音を touchstart や pointerdown で始めている | 音はスタートボタンで始める |
2 つ以上あてはまることもよくあります。表の上から順に直すと、あとの症状の原因が見つけやすくなります。
キーボードだけのゲームに、タップのボタンを足す
AI のゲームの多くは、keydown で押されたキーを覚えておき、ゲームのループで「左が押されているあいだは左へ動かす」と読みます。スマホにはキーボードがないので、このままではキャラクターに指示が届きません。
直し方は、画面に操作ボタンを置き、ボタンを押しているあいだ、キーを押したときと同じ印をつけることです。キーボードとボタンが同じ表に書き込むので、パソコンの操作はそのまま残ります。
AI にはこう頼みます。
このゲームを、スマホのタップでも操作できるようにして。
- パソコンの矢印キーとスペースキーの操作は、そのまま残す
- 画面の下に「左」「右」「ジャンプ」のボタンを置き、押しているあいだはキーを押したのと同じ動きにする
- ボタンは pointerdown・pointerup・pointercancel で扱い、指をボタンの外へずらしてから離しても、押したままにならないようにする
- ボタンは 1 辺 48 px 以上にして、長押しで文字が選ばれたりメニューが出たりしないようにする
- 1 つの HTML ファイルのままにして、ほかのサイトからの読み込みや fetch、eval は足さない
自分で足すときは、次の 3 つが中心になります。ボタンの HTML、ボタンとキーボードの両方を受け取るスクリプト、ボタンの CSS です。ゲームのループがキーを読むところは、held.ArrowLeft のように、この表を読む形にそろえます。
<div class="pad">
<button type="button" data-code="ArrowLeft" aria-label="左">◀</button>
<button type="button" data-code="ArrowRight" aria-label="右">▶</button>
<button type="button" data-code="Space" aria-label="ジャンプ">●</button>
</div>
// キーボードとタップのボタンが、同じ表に「押されている」を書き込む
const held = {};
addEventListener("keydown", (e) => { held[e.code] = true; });
addEventListener("keyup", (e) => { held[e.code] = false; });
for (const button of document.querySelectorAll(".pad [data-code]")) {
const code = button.dataset.code;
button.addEventListener("pointerdown", (e) => {
button.setPointerCapture(e.pointerId);
held[code] = true;
});
const release = () => { held[code] = false; };
button.addEventListener("pointerup", release);
button.addEventListener("pointercancel", release);
button.addEventListener("lostpointercapture", release);
}
// ゲームのループでは、たとえば: if (held.ArrowLeft) player.x -= speed;
.pad { position: fixed; left: 0; right: 0; bottom: 16px; display: flex; justify-content: space-between; padding: 0 16px; }
.pad button {
min-width: 56px; min-height: 56px; font-size: 24px;
touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}
/* マウスで操作する画面では、ボタンを隠す */
@media (hover: hover) and (pointer: fine) { .pad { display: none; } }
ゲームが e.code ではなく e.key でキーを見ているときは、data-code の名前もそれに合わせます。スペースキーは、e.code では Space、e.key では半角スペース 1 文字です。
setPointerCapture は、押したあとに指がボタンの外へずれても、指を離したことをこのボタンに届けるためのものです。
ボタンの大きさについて、Apple のデザインの指針は、押せる範囲を原則として 44×44 pt 以上としています。pt は Apple が画面の設計に使う単位で、CSS の px とは別のものです。このページの例は Web のボタンなので、CSS で、頼み方では 1 辺 48 px 以上、コードでは 56 px にしています。どちらの大きさでも、自分のスマホで指で押しやすいかを確かめてください。
タップした場所とずれるときは、キャンバスの座標を換算する
キャンバスのゲームは、<canvas width="400" height="600"> のように決めた内部の大きさで座標を計算します。スマホでは CSS でキャンバスを画面の幅まで縮めることが多く、そうすると見た目の 1 px と内部の 1 px がそろいません。指の位置をそのまま使うと、縮めた分だけずれます。
直すには、指の位置からキャンバスの左上の位置を引き、見た目の幅で割って、内部の幅を掛けます。
// 指やマウスの位置を、ゲームが使う座標に直す
// W と H は、ゲームが座標に使う幅と高さ(多くは canvas.width と canvas.height)
function toGame(canvas, e, W = canvas.width, H = canvas.height) {
const r = canvas.getBoundingClientRect();
return {
x: ((e.clientX - r.left) * W) / r.width,
y: ((e.clientY - r.top) * H) / r.height,
};
}
canvas.addEventListener("pointerdown", (e) => {
const p = toGame(canvas, e);
// p.x と p.y で、押した場所を判定する
});
pointerdown は、マウスのクリックでも、ペンでも、指のタッチでも届きます(MDN の Pointer events)。パソコンのマウス操作も、この 1 つで受け取れます。
画面の細かいスマホでキャンバスの絵がぼやけるときは、devicePixelRatio を掛けた大きさで内部を作る方法が、MDN の devicePixelRatio のページにあります。その作りに変えたときも、W と H には、ゲームが座標に使う幅と高さを渡します。
AI に頼むなら、こう送ります。
スマホでタップした位置がずれるので直して。キャンバスの見た目の大きさと内部の大きさが違っても、getBoundingClientRect で換算して、押した場所とゲームの座標が一致するようにして。マウスのクリックも同じ処理で受け取って。
画面が小さい・はみ出すときは、画面の大きさに合わせる
スマホで全体が小さく表示されるときは、<head> に次の 1 行があるかを見ます。
<meta name="viewport" content="width=device-width, initial-scale=1">
MDN によると、スマホのような細い画面のブラウザには、ページを画面より広い仮の画面(MDN の例では 980 px)に描いてから、縮めて表示するものがあります。この 1 行は、仮の画面の幅を、スマホの画面の幅に合わせます。
拡大を止める指定(user-scalable=no や maximum-scale=1)は足しません。MDN は、拡大できないと視力の弱い人がページを読めなくなると注意しています。iPhone の Safari も、iOS 10 から、ページの指定にかかわらず指で拡大できるようにしています(Apple の Safari 10 のリリースノート)。ゲーム中に画面が拡大されてしまうのは、次の節のとおり、キャンバスと操作ボタンの上だけで止めます。
下が切れるときは、高さの 100vh を見ます。MDN によると、いまのブラウザの 100vh は、アドレスバーが隠れたときの大きい画面の高さです。アドレスバーが出ているあいだは、その分だけ下がはみ出します。アドレスバーの出入りに合わせて高さを変えるなら 100dvh を使います。
スマホで画面に収まるようにして。<meta name="viewport" content="width=device-width, initial-scale=1"> を入れ、拡大を禁止する指定は入れないで。キャンバスは縦横比を保ったまま画面に収め、高さは 100vh ではなく 100dvh で決めて。縦向きと横向きを切り替えたときも描き直して。
指でなぞると画面が動くときは、指の動きをゲームに渡す
画面の上の指の動きは、ふつうはブラウザがスクロールや拡大に使います。キャンバスの上の指の動きをゲームに渡すには、CSS の touch-action で、その要素の上ではブラウザに使わせないと伝えます。
/* ゲームの画面と操作ボタンの上だけ、スクロールと拡大をブラウザにさせない */
canvas,
.pad button {
touch-action: none;
}
touch-action: none は、ページ全体(html や body)には付けません。MDN は、touch-action: none がブラウザの拡大の機能を妨げ、視力の弱い人が読めなくなることがあると注意しています。遊び方の説明や結果の画面は、ふつうにスクロールも拡大もできるように残します。
AI がタッチのイベント(touchstart、touchmove)で書いているときは、もう 1 つ確かめます。MDN によると、window や document、body に付けた touchstart と touchmove は、指定しなければ passive として扱われ、その中で preventDefault() を呼んでも効きません。document.addEventListener("touchmove", …) の中で e.preventDefault() を呼んでいるのに画面が動くのは、このためです。上の touch-action を足すか、キャンバス自身に付けて { passive: false } を指定します。
ボタンから指を離してもキャラクターが止まらないときは、pointercancel を見ます。MDN によると、pointercancel は、ブラウザが指の動きをスクロールや拡大に使い始めたとき、画面の向きが変わったとき、同時に触れる指が多すぎるときなどに届きます。このとき pointerup は届かないので、受け取らないと「押されている」のまま残ります。前の節のコードは、pointercancel と lostpointercapture でも印を外しています。
音が出ないときは、音をスタートボタンで始める
ブラウザの多くは、ページを開いた人がまだ何も操作していないうちに音を鳴らすことを止めています(MDN の Autoplay guide)。MDN の Web Audio の手引きは、守ることを「Create or resume context from inside a user gesture」(ユーザーの操作の中で、音の準備を作るか再開する)とまとめています。操作の外で作った AudioContext は suspended(止まった状態)で始まり、操作の中で resume() を呼ぶまで鳴りません。
どの操作が数えられるかにも注意します。MDN の User activation によると、指のタッチで数えられるのは指を離したとき(pointerup と touchend)で、触れた瞬間の pointerdown は入りません。Safari のエンジンである WebKit の説明(2016 年)でも、<audio> や <video> の play() が動くのは、touchend、click、keydown などの処理から直接呼んだときです。touchstart で音を始めるゲームが iPhone で鳴らないのは、このためです。
直し方は、「スタート」のボタンを置き、その click の中で音の準備を始めることです。click は指を離したあとに届くので、スマホでもパソコンでも条件を満たします。AudioContext を作るのも、resume() と play() を呼ぶのも、await や setTimeout のあとに回さず、click の処理の中でそのまま始めます。音の準備は失敗することがあるので、失敗してもゲームは始まるように、ゲームの開始は音と切り離しておきます。
// 音は、スタートボタンの click の中で、待たずにそのまま始める
let audio = null;
startButton.addEventListener("click", () => {
try {
if (!audio) audio = new AudioContext();
if (audio.state === "suspended") audio.resume().catch(() => {});
} catch {
// Web Audio を使えないときは、音なしで続ける
}
try {
bgm.play().catch(() => {});
} catch {
// BGM を鳴らせないときも、音なしで続ける
}
startGame(); // 音が鳴っても鳴らなくても、ゲームは始める
});
bgm は <audio> で流す BGM です。使っていなければ、2 つ目の try ごと消します。play() は鳴らせないとき NotAllowedError で失敗し(MDN の Autoplay guide)、resume() も失敗することがあります。どちらも .catch() で受け、AudioContext を作れないときは try で受けるので、どれが失敗しても、最後の startGame() まで進みます。
それでも iPhone で鳴らないときは、消音モードを確かめます。WebKit のバグ報告には、消音モードの iPhone で <audio> は鳴り、Web Audio(AudioContext)の音は鳴らない、という報告があります。この報告への 2024 年 9 月の返信には、iOS 17 から navigator.audioSession.type = "playback" を指定すれば消音モードでも止まらない、と書かれています。ただ、消音モードは遊ぶ人が自分で選んだ設定です。教室や電車の中で開かれるゲームなら、消音モードでは鳴らないまま、画面だけで遊べるようにしておくほうが親切です。
スマホで音が出ないので直して。ページを開いたときには音を鳴らさず、AudioContext も作らないで。「スタート」ボタンの click の中で、await や setTimeout を使わずに、AudioContext を作るか resume して、BGM の play() もそこで呼んで。AudioContext を作れないときや、resume() や play() が失敗したときも、ゲームは音なしで始まるようにして。
直したゲームをスマホで確かめる 5 つの手順
1. 直したファイルを Convika に入れる
はじめてなら、app.convika.com で登録します。このページのボタンやリンクから登録すると、登録が終わった時点でアップロードの画面が開きます。「HTML ファイルからページを公開」の画面で、「ファイルから」にファイルを入れるか、「コードから」にコードを貼り付けて、「プレビューをつくる」を押します。2 MB まで置けて、アップロードに AI クレジットは使いません。
もう公開しているゲームを直したときは、ページの画面の「HTML ファイルで更新」で、直したファイルを選ぶかコードを貼り付け、「新しいバージョンとしてアップロードする」を押します。公開するまで、遊ぶ人には前の版が出ます。
2. 管理画面のプレビューを、自分のスマホで開く
「プレビューを開く」を押すと、公開する前のゲームを、スクリプトが動く状態で開けます。プレビューの URL は非公開で、開けるのは 3 分間だけです。スマホで開くには、URL を自分あての LINE やメールに送ってすぐに開くか、スマホのブラウザで管理画面にログインして「プレビューを開く」を押します。
登録せずに作るプレビューは、スクリプトを止めて表示するので、ゲームの動きは確かめられません。確かめるのは、登録してから管理画面で開くプレビューです。
3. 表の症状を、1 つずつ指で確かめる
スマホで次の 5 つを試します。
- キャラクターを、タップのボタンで動かせるか。
- ボタンを押したまま指をボタンの外へずらし、そこで指を離したとき、キャラクターが止まるか。
- タップした場所が、ゲームの中で反応してほしい場所と合っているか。
- 縦向きと横向きを切り替えても、画面に収まっているか。
- 「スタート」を押すと音が鳴るか。iPhone では、消音モードを切った状態でも試します。
最後に、パソコンでもプレビューを開き、矢印キーの操作が前と同じかを確かめます。Free のページでは、プレビューにも、公開したあとと同じように下に Convika のバナーが出ます。操作ボタンが隠れていないかも見ます。
4. 公開する
はじめての公開なら、「ページを公開する」を押し、「このページを開ける人」で「一般公開」を選んで「次へ」を押します。はじめての公開では、続いて大きな「無料で公開する」のボタンが出ます。押すとすぐに公開され、ページの下に Convika のバナーが出ます。出したくないときは、その下の「Convika のバナーなしで公開する」から Pro のお申し込み画面に進みます。
もう公開しているゲームなら、「プレビュー v2 ができました」のように出たあとの「同じリンクで v2 を公開する」を押し、確認の画面で「公開する」を押します。URL は変わらないので、送ったリンクや QR コードはそのまま使えます。
5. 遊ぶ人のスマホでも開いてもらう
スマホの動きは、機種とブラウザの組み合わせで変わることがあります。手元にない機種は、公開した URL を友だちに送って遊んでもらい、直すところが見つかったら、手順 1 の「HTML ファイルで更新」から直します。同じ URL のまま入れ替わります。
直しても動かないときに見るところ
タップや音を直しても動かないときは、Convika のページで止めている書き方を使っていないかを見ます。
evalとnew Function。 文字からコードを組み立てる書き方は、Convika のページでは動きません。AI に「eval と new Function を使わない書き方にして」と頼みます。- ほかのサイトとの通信。 Convika のページのスクリプトが fetch などで通信できるのは、自分のアドレスだけです(Pro は、アクセス解析ツールと、持ち主が登録した広告の送信先が加わります)。ほかのサーバーに置いたランキングや通信対戦は動きません。
- ほかのサイトから、ライブラリの機能で読み込む画像と音。 p5.js や Phaser の読み込み機能に、ほかのサイトの画像や音の URL を渡すと止まります。ファイルに埋め込んだ画像と音なら読み込めます。試した結果は、ガイド ChatGPT・Claude・Gemini で作ったゲームを、友だちがログインなしでスマホで遊べるように公開する にあります。
よくある質問
AI で作ったゲームがスマホで動かないのはなぜですか?
多くは、操作をパソコンのキーボードとマウスだけで受け取る作りになっているからです。スマホにはキーボードがないので、矢印キーで動くキャラクターに指示が届きません。ほかに、キャンバスの座標のずれ、指の動きがスクロールに使われること、音を始めるタイミングが原因になります。このページの表で、症状から原因を見分けられます。
スマホでタップが効かないときはどうすればいいですか?
コードに keydown しかなければ、画面に操作ボタンを置き、pointerdown と pointerup で、キーを押したときと同じ印をつけます。タップした場所とずれるなら、getBoundingClientRect() でキャンバスの見た目の大きさを測り、ゲームの座標に換算します。どちらの直し方でも、パソコンのキーボード操作は残せます。
iPhone でゲームの音が出ないのはなぜですか?
ページを開いたときや、指が触れた瞬間(touchstart)に音を始めていると、iPhone の Safari は鳴らしません。「スタート」ボタンの click の中で AudioContext を作るか resume() を呼び、BGM の play() もそこで呼びます。消音モードの iPhone では、Web Audio の音が鳴らないという報告もあるので、消音モードを切っても試します。
ゲーム中に画面がスクロールしたり拡大されたりするのを止めるには?
キャンバスと操作ボタンに、CSS の touch-action: none を付けます。ページ全体や、viewport の user-scalable=no で拡大を止めるのはやめます。説明文まで拡大できなくなり、iPhone の Safari は iOS 10 からその指定を無視します。
パソコンのキーボード操作は残せますか?
残せます。キーボードとタップのボタンが、同じ「押されている」の表に書き込む作りにすれば、ゲームのループは 1 つのまま、どちらでも動きます。マウスのクリックは、pointerdown で指のタッチと一緒に受け取れます。
直したゲームをスマホで試すにはどうすればいいですか?
スクリプトが動く場所に置いて、スマホのブラウザで開きます。Convika なら、ファイルをアップロードして管理画面の「プレビューを開く」を押すと、公開する前のゲームをスマホで遊べます。プレビューの URL が開けるのは 3 分間だけなので、自分あてに送ったらすぐに開きます。
出典
確認日はどれも 2026 年 10 月 26 日で、どのページも英語です。
- Pointer events(MDN、2026 年 10 月 26 日に確認): マウス、ペン、タッチを 1 つのイベントで扱えること
- Element: pointercancel event(MDN、2026 年 10 月 26 日に確認):
pointercancelが届くとき - touch-action(MDN、2026 年 10 月 26 日に確認):
noneとmanipulation、拡大の妨げについての注意 - EventTarget: addEventListener() method(MDN、2026 年 10 月 26 日に確認):
window・document・bodyのtouchstartとtouchmoveが passive になること - Viewport meta tag(MDN、2026 年 10 月 26 日に確認):
width=device-width、980 px の例、user-scalable=noの注意 - CSS length(MDN、2026 年 10 月 26 日に確認):
vhとdvhの違い - Window: devicePixelRatio property(MDN、2026 年 10 月 26 日に確認): キャンバスをはっきり描く方法
- User activation(MDN、2026 年 10 月 26 日に確認): ユーザーの操作として数えられるイベント
- Web Audio API best practices(MDN、2026 年 10 月 26 日に確認): 「Create or resume context from inside a user gesture」
- Autoplay guide for media and Web Audio APIs(MDN、2026 年 10 月 26 日に確認):
play()のNotAllowedError - New <video> Policies for iOS(WebKit、2016 年 7 月 25 日公開、2026 年 10 月 26 日に確認):
touchend、click、keydownから呼ぶ再生 - Bug 237322: webaudio api is muted when the iOS ringer is muted(WebKit Bugzilla、2026 年 10 月 26 日に確認): 消音モードと Web Audio、
navigator.audioSession - What's New in Safari 10.0(Apple、2026 年 10 月 26 日に確認): 指での拡大がいつもできること
- Buttons(Apple Human Interface Guidelines、2026 年 10 月 26 日に確認): 押せる範囲は 44×44 pt 以上
次のステップ
HTML ページにパスワードをかけて、知っている人だけに見せる方法
JavaScript で作った画面は、ソースを開けばパスワードが読めてしまいます。ChatGPT や Claude で作った HTML をアップロードし、自分のドメインのままサーバー側で確かめるパスワード付きのページにする方法を説明します。
関連記事
- ChatGPT・Claude・Gemini で作ったゲームを、友だちがログインなしでスマホで遊べるように公開するChatGPT・Claude・Gemini で作ったゲームを、友だちがログインなしでスマホで遊べるように公開する方法。itch.io、GitHub Pages、Netlify Drop、CodePen、Convika の無料サービス 5 つの比較と手順です。
- Gemini Canvas で作ったゲームを、友だちがスマホで遊べるリンクにするGemini の共有リンクは gemini.google.com で開き、Gemini のモバイルアプリでは開けません。コードを取り出して、スマホのブラウザで開くリンクにする手順です。
- ChatGPT でブラウザゲームを作って、友だちにリンクで遊んでもらうまでChatGPT のキャンバスはいまのモデルから外れ、ページを公開する ChatGPT Sites は Free と Go では使えません。ChatGPT で作ったゲームを HTML ファイル 1 つにして、自分のスマホで試し、友だちがアカウントなしで遊べるリンクにする手順です。
- Claude で作ったゲームを、Claude を使っていない友だちにも遊んでもらうAnthropic のヘルプによると、共有したアーティファクトは Claude のアカウントがないと開けません。ゲームのコードを取り出して、友だちがスマホのブラウザでログインなしに遊べるリンクにする手順です。
- AI で作ったページを後から直したい。URL も QR コードもそのままで差し替える方法公開して配ったあとに誤字や日付の間違いが見つかったら。ChatGPT や Claude に直した HTML をもらい、Convika の「HTML ファイルで更新」で入れ替えると、配ったリンクも印刷した QR コードも、そのまま新しい内容を開きます。
- AI で作ったゲームがバズったら、公開は止まる? 無料の公開先のアクセス上限と、ピークでも止めない方法ChatGPT や Claude で作ったゲームが急に広まったら、無料の公開先はどこまで持つか。GitHub Pages、Netlify、Cloudflare Pages、Vercel、itch.io、Convika などの上限と、超えたときに起きること、広まっている間もゲームを止めない方法をまとめました。