ブラウザゲームでは、操作の楽しさとアクセシビリティを両立させる設計が重要です。この記事では、Astro と React Islands を使って、ドラッグ操作だけに依存しないサイズ比較ゲームを構築した際の考え方をまとめます。
実例として開発した Size It Up Party は、基準となる輪郭と対象の輪郭を比較し、実際の大きさを推測する無料ブラウザゲームです。
なぜページ全体を React にしないのか
ゲーム画面にはインタラクティブな状態管理が必要ですが、遊び方、FAQ、説明文、ナビゲーションまでクライアント JavaScript にする必要はありません。
Astro で静的 HTML を生成し、ゲーム本体だけを React island として読み込むと、次の利点があります。
- 主要な説明文が初回 HTML に含まれる
- JavaScript の読み込み範囲を小さくできる
- SEO とアクセシビリティの基礎を保ちやすい
- ゲーム状態を独立したコンポーネントに閉じ込められる
例として、Astro ページ側では次のように island を配置できます。
---
import GameZone from "../components/game/GameZone.tsx";
---
<main>
<h1>Size It Up</h1>
<p>Compare the silhouettes and estimate the real size.</p>
<GameZone client:load />
<section>
<h2>How to play</h2>
<p>Adjust the target, lock your guess, and reveal the answer.</p>
</section>
</main>
ドラッグ以外の操作を用意する
輪郭を直接ドラッグして拡大・縮小する操作は直感的ですが、キーボード利用者には代替手段が必要です。そこで同じ値を変更する複数の入力方法を用意します。
- ポインターまたはタッチによる直接操作
- 明確なラベル付きスライダー
- 増減ボタン
- 矢印キーによる微調整
- 数値入力と単位選択
重要なのは、これらが別々の状態を持たないことです。すべて同じ正規化された推測値を更新し、表示だけを同期させます。
function clampGuess(value: number, min: number, max: number) {
if (!Number.isFinite(value)) return min;
return Math.min(max, Math.max(min, value));
}
状態変化を色だけで伝えない
「回答をロックした」「正解を表示した」「範囲外の値を入力した」といった状態は、色の変化だけでは十分ではありません。画面上のテキスト、フォーカス状態、必要に応じた live region を組み合わせます。
ただし、ドラッグ中の値を毎フレーム読み上げるとスクリーンリーダー利用者を妨げます。操作中は視覚表示を更新し、確定時やエラー時に限って短いメッセージを通知する方が実用的です。
レイアウトシフトを防ぐ
正解表示やスコア表示を後から追加すると、ゲーム領域が大きく動く場合があります。初期状態から必要な高さを確保し、同じ領域内で表示を切り替えることで、モバイルでも操作位置が安定します。
また、360px 程度の画面幅でも主要操作が利用できるようにし、タッチ対象は十分な大きさを確保します。
まとめ
Astro と React Islands の組み合わせは、静的コンテンツを守りながら、必要な場所だけに複雑なインタラクションを追加できます。ゲームの楽しさをドラッグ操作だけに閉じ込めず、キーボード、タッチ、数値入力を同じ状態モデルにつなぐことで、より多くの人が遊べる設計になります。
技術選定そのものより大切なのは、操作方法が違っても同じゲーム体験と結果に到達できることです。