ブラウザゲームの画面サイズ対応:全画面・縦横比・リサイズ
遊びをつくる執筆にClaudeを使用しています。

ブラウザゲームを作るとき、「自分のパソコンでは綺麗に表示されるのに、別の端末で見たら崩れていた」という経験をした方は多いはずです。スマートフォン・タブレット・ワイドモニターと、プレイヤーの環境はさまざまで、どの画面でも意図した見た目を保つには、意識的な設計が必要です。 この記事では、全画面表示・縦横比(アスペクト比)の維持・ウィンドウリサイズへの追従という三つの課題を整理し、それぞれいつどの手法を選ぶべきかの判断基準と、実装の要点を示します。
この記事の目次
画面サイズ対応の三つの問い
ゲームの画面サイズ対応を考えるとき、実際には次の三つは別々の問いです。
- どこまでを「ゲーム領域」とするか ── 固定サイズか、ブラウザ全体に広げるか。
- 縦横比をどう扱うか ── 比率を固定するか、自由に変形させるか。
- ウィンドウサイズが変わったとき何をするか ── リサイズに追従するか、無視するか。
この三つは組み合わせによって挙動が大きく変わります。たとえば「縦横比を固定しつつブラウザ全体に広げる」と「常にブラウザいっぱいに引き伸ばす」は、どちらも「全画面っぽく見える」ものの、実装も見た目も異なります。まず自分のゲームがどの組み合わせを必要とするかを決めることが、余計な手戻りを防ぐ最初のステップです。
固定サイズ・スケール・フレキシブルの三択
画面サイズへの対応戦略は大きく三つに分類できます。
固定サイズ(Fixed)
ゲームのcanvasやコンテナに width: 640px; height: 480px; のように固定値を与え、それ以上広げない方法です。実装が最もシンプルで、座標計算がピクセル単位で一致するため、パズルや入力精度が重要なゲームで安定します。ただし小さな画面では一部が画面外に出ることがあり、モバイルとの相性は悪くなります。
スケール(Scale)
ゲーム内の論理解像度(たとえば640×480)は固定したまま、表示倍率だけを変えて画面に合わせる方法です。CSS の transform: scale() や Canvas の drawImage による描画スケールを使います。縦横比を維持したままブラウザ全体に表示したい場合はこの方法が基本になります。ロジック側がピクセルを意識しなくて済むため、後から解像度変更が必要になったときも改修コストが低く抑えられます。
フレキシブル(Flexible)
ウィンドウサイズに合わせてゲーム領域そのものが伸縮する方法です。CSSのFlexboxや vw・vh 単位を使い、要素がウィンドウに追従します。UIカードゲームやボードゲームのように、配置を相対的に決められるものには向いています。一方、ピクセル単位の当たり判定を持つアクションゲームには不向きで、描画とロジックの座標系が常に一致するよう注意が必要です。
縦横比を維持して全画面に近づける実装
多くのゲームで求められるのは「縦横比16:9を保ちつつ、できるだけ画面を広く使う」という挙動です。ここではCanvasを使う場合の考え方を整理します。
基本の発想は「論理サイズを固定し、表示サイズをウィンドウに合わせてスケールする」です。具体的には次の手順になります。
- HTMLのcanvas要素にはCSSサイズを指定せず、canvas.width と canvas.height(論理解像度)だけを決める。
- ウィンドウサイズからアスペクト比を計算し、収まる最大サイズを求める。ウィンドウの縦横比がゲームより横長なら高さを基準に、縦長なら幅を基準にスケール率を決める。
- 求めたCSSサイズを canvas.style.width と canvas.style.height に設定する。
- canvasを中央に配置するには、親要素を display: flex; justify-content: center; align-items: center; width: 100vw; height: 100vh; にするのが手軽です。
このとき body と html の margin・padding をゼロにし、overflow: hidden を設定しておかないと、スクロールバーが現れてサイズ計算がずれる場合があります。見落としやすいポイントです。
マウスやタッチの座標をゲームロジックに渡すときは、CSSサイズと論理サイズの比率で割り戻す必要があります。canvas.getBoundingClientRect() でcanvasの表示位置とサイズを取得し、そのサイズと canvas.width の比率を使って補正します。スケール対応後に「クリックがずれる」と感じたら、まずここを疑ってください。
リサイズへの追従
ウィンドウサイズが変わったときにゲーム表示を追従させるには、window.addEventListener('resize', handler) でリサイズを検知してスケール計算をやり直します。
注意点は二つあります。一つ目はリサイズイベントの頻度です。ウィンドウのドラッグ中は非常に高頻度でイベントが発火するため、毎回重い処理を走らせるとパフォーマンスが落ちます。一定時間内の最後の呼び出しだけを実行する「デバウンス」処理を挟むのが一般的です。
二つ目はゲーム状態との整合性です。スケール率の変更はあくまで表示側の操作なので、論理解像度で管理しているゲーム内座標には影響しません。ただし「リサイズ時にcanvas要素を作り直す」実装にしてしまうと描画内容がクリアされます。論理解像度は変えず、CSSサイズだけを変更する設計にしておくと安全です。
スマートフォンでは画面の向き(縦持ち・横持ち)の切り替えもリサイズとして扱われます。向きの変化を専用に検知したい場合は screen.orientation APIや orientationchange イベントを使う方法もありますが、リサイズハンドラで十分カバーできるケースがほとんどです。
Fullscreen APIで本当の全画面にする
ブラウザのアドレスバーやタブまで消して「本当の全画面」にするには、Fullscreen APIを使います。element.requestFullscreen() を呼ぶと対象要素が画面全体に広がり、document.exitFullscreen() で戻せます。
重要な制約として、Fullscreen APIはユーザー操作(クリック・タップなど)のイベントハンドラ内からしか呼べません。ページ読み込み直後に自動で全画面にしようとしても多くのブラウザで拒否されます。「全画面でプレイ」ボタンを設ける設計が現実的です。
全画面時はcanvasがウィンドウ全体に広がるため、前述のスケール計算が正しく動いていれば縦横比は自動的に維持されます。全画面を前提としない場合でも、スケール対応を先に済ませておくとFullscreen API追加時の工数がほぼゼロになります。
また、CSSで全画面に近い見た目を作る方法として position: fixed; top: 0; left: 0; width: 100%; height: 100%; という指定もあります。こちらはブラウザのUIが残りますが、手軽に「ほぼ全画面」を実現できます。Fullscreen APIへの対応を後回しにしたい段階ではこの方法で十分です。
どの方針を選ぶか:判断の目安
- モバイル非対応でいい、PC専用パズルなど、推奨アプローチ:固定サイズ+中央配置でも十分
- PC・スマホ両対応、アクション・シューティング、推奨アプローチ:論理解像度固定+CSSスケール
- カードゲーム・UI中心で要素の相対配置でよい、推奨アプローチ:フレキシブルレイアウト
- 没入感を最大化したい、推奨アプローチ:Fullscreen API+スケール
ゲームのジャンルと対象デバイスが決まれば、大半のケースは「論理解像度固定+CSSスケール」に落ち着きます。入力座標の補正を忘れず、リサイズをデバウンスで間引くという二点を押さえれば、多くのブラウザで安定した挙動が得られます。
次の行動
今作っているゲームのcanvasに canvas.getBoundingClientRect() を使った座標補正が入っているか確認してみてください。入力ずれの原因はここにあることがほとんどです。スケール対応ができたら、Fullscreen APIと組み合わせて「全画面ボタン」を追加するのが次のステップになります。できあがったゲームはHTMLファイルやZIPファイルとしてアソバースに投稿し、さまざまな環境のプレイヤーに試してもらうことで、想定外の崩れを早期に発見できます。
参考資料
- MDN Web Docs「Fullscreen API」
- MDN Web Docs「Element: requestFullscreen() method」
- MDN Web Docs「Canvas API」
- HTML Living Standard(WHATWG)

