陣取りゲーム (Qix系) - 768x768 絵文字版
本記事は、AI(人工知能)を用いてゲームのコーディングおよび説明記事の執筆を行いました。クリエイティブ分野における AI 活用の可能性と透明性について示すことを目的としています。
説明
ゲームの概要
このゲームは、フィールド内を動き回る敵をよけながら線で領域を囲み、自分の陣地を広げていく「Qix(クイックス)」タイプの陣取りゲームです。プレイヤー(🙂
)を操作して、フィールド全体の80%以上を占領するとステージクリアとなります。
遊び方
1. プレイヤーの操作
- 移動:
矢印キー
またはW
,A
,S
,D
キーでプレイヤー(🙂
)を上下左右に動かします。- プレイヤーは、フィールドの外周や、すでに自分が確保した安全な陣地の上を自由に移動できます。
- 陣地を確保する(線を引く):
- 安全な陣地の上で
スペースキー
を押すと、線を引くモードになります。 - そのまままだ確保していない領域(空白の領域)へ移動すると、軌跡に沿って線が引かれます。
- 線で領域を囲み、再び安全な陣地に戻ると、囲んだ領域が自分の陣地になります。エリアを確保すると、確保した割合(%)がプレイヤーの近くに表示されます。
- 安全な陣地の上で
- 線を引くのをキャンセルする:
- 線を引いている途中で
スペースキー
を離すと、それまで引いてきた線を高速で戻り、線を引く操作をキャンセルできます。
- 線を引いている途中で
2. ルールと注意点
- 敵キャラクター(
👾
):- フィールド内には敵(
👾
)が動き回っています。レベルが上がると敵の数が増え、動きも速くなります。
- フィールド内には敵(
- ミスになる条件:
- 線を引いている最中に、プレイヤー(
🙂
)が敵(👾
)に接触する。 - 引いている途中の線に敵(
👾
)が接触する。 - 画面上部のタイムバーで示される制限時間(90秒)がゼロになる。
- 線を引いている最中に、プレイヤー(
- ミスをすると:
- 残機が1つ減ります。残機がなくなるとゲームオーバーです。
- 残機が残っている場合は、安全地帯の上をプレイヤーが自動で移動します。任意のキーを押すと、その場所からゲームを再開できます。
3. その他の操作
R
キー: ゲームを最初からやり直します(リスタート)。H
キー: ヘルプの表示・非表示を切り替えます。
このゲームは、一度に大きな領域を狙うのではなく、敵の動きを見ながら少しずつ着実に陣地を広げていくのが攻略の鍵となります。
制作の仕様
以下の仕様を元にChatGPT5にてコーディングを行いました。
## 1. 概要
* **ジャンル**:Qix系陣取りアクション
* **実行環境**:単一HTML(Canvas 2D、Vanilla JS)、依存ライブラリなし
* **画面解像度**:768×768 固定(CSSで枠・HUD表示)
* **入力**:キーボード(矢印/WASD/Space/R/H)、マウス/タップでフォーカス付与
* **描画**:背景2層(通常/クリア用)+マスク合成+前景(未確定線・プレイヤー・敵・UI)
* **フェイルセーフ**:画像未読込時のフォールバック背景、エラー表示バー、フォーカス誘導、MISS直後のフレーム中断
---
## 2. 目的と勝利条件
* **目的**:フィールド(外枠内)の**塗りつぶし率**を\*\*目標 GOAL=80%\*\*に到達させる。
* 到達時は**CLEAR**状態に遷移し、**5秒**の演出後に次レベルへ自動進行。
---
## 3. 主要パラメータ(定数)
* 盤面:`W=768`, `H=768`, **セルサイズ** `CELL=6` → **グリッド** `GW=128`, `GH=128`
* 目標取得率:`GOAL=80`
* 初期残機:`INIT_LIFE=3`
* ステージ持ち時間:`STAGE_TIME=90,000 ms(1分30秒)`
* 画像パス:`IMG_DIR="img/"`(`backXX.jpg`, `clearXX.jpg`)
* プレイヤー/敵表示:絵文字 `PLAYER="🙂"`, `ENEMY="👾"`
---
## 4. ゲームフロー & ステートマシン
### 状態
* `TITLE` → 初期化
* `READY` → 開始前短時間の待機
* `PLAY` → 通常プレイ
* `RESPAWN` → MISS後の線上自動歩行(任意キーで再開地点確定)
* `CLEAR` → クリア演出(フェード+文字表示)
* `FAIL` → 残機0でゲームオーバー
### 遷移
* 起動:`TITLE → READY(startLevel)→ PLAY`
* クリア:`PLAY`で取得率≥目標 → `CLEAR` →(5秒後)次レベル`READY`
* ミス:`PLAY`中に被弾/時間切れ → 残機減 → `RESPAWN`(任意キー)→ `PLAY`/残機0なら`FAIL`
---
## 5. 盤面モデル
* **セル値**
* `G_EMPTY=0`:未取得領域
* `G_FILL=1`:取得済み領域
* `G_TEMP=2`:描画中の仮線(確定前)
* `G_EDGE=3`:外周の固定線(初期に上下左右の枠を生成)
* **初期化**:全セル`EMPTY`、外周を`EDGE`で囲む。
---
## 6. プレイヤー
* **位置/移動**:グリッド座標(整数)/速度1セル/フレーム
* **待機→描線トグル**:
* **Space**(押下)で描線開始条件:現在地が`EDGE`または`FILL`
* **Space**(離上)で描線終了:**戻りモード**(pathを逆走して起点へ安全復帰)
* **描線ルール**:
* 空白へ進入すると`G_TEMP`で線を刻む。
* 直近`BACKTRACK_OK=4`セル以内の自己交差は**戻り削除**(それ以外はブロック)。
* `FILL/EDGE`に戻った時点で**確定(solidify)**。
---
## 7. 塗り確定(solidify)アルゴリズム
1. `G_TEMP` を **一括で `G_FILL`** に変換。
2. **可視配列 `vis`** をクリア。
3. **敵の位置から空白領域へのBFS(floodFromEnemies)** を実行し、到達可能な`EMPTY`を`vis=1`に標識。
4. `vis=0`の`EMPTY`は**敵から隔離された領域**として\*\*`G_FILL`に変換\*\*。
→ Qix系の「線で囲って領域を取る」挙動を再現。
---
## 8. 敵(AI)
* **レベル毎の数**:`lvEnemies(l)`
* Lv1–2:1体 / 3–4:2体 / 5–6:3体 / 7–8:4体 / 9+:5体
* **移動速度**:`baseES(l)=min(0.75+0.07*(l-1), 2.6)` を基準にランダム少変動
* **挙動**:
* **プレイヤー距離依存の意識度 `aware`** と\*\*ランダム力(OUノイズ)\*\*を混合
* **徘徊目標**(空白`EMPTY`内ランダム)を周期的に更新
* \*\*アイドル閾値 `IDLE_THRESH=60`\*\*超の静止で警戒低下・接近抑制(引き離し成分)
* **境界/塗り/線**の侵入不可チェック(`enemyWalkable`)
* **線ヒット判定**:
* 円と`G_TEMP`の交差(`circleHitsTemp` / `sweepHitsTemp`)
* **描線中・戻り中**のプレイヤー円との接触
→ いずれも**MISS**
---
## 9. ミス(MISS)とリスポーン
* **ミス要因**:
* 敵が`G_TEMP`(描線)に接触 / プレイヤー円と衝突
* **時間切れ**(タイマー0)
* **処理**:残機-1、未確定線を全て消去。残機0で`FAIL`。
* **RESPAWN**:
* **時計回り**に**ゆっくり自動歩行**(`slowInterval=140ms`)。
* 任意キー押下で即座に`PLAY`復帰(その位置から再開)。
---
## 10. 進行・タイマー
* **HUD時間**は`PLAY/RESPAWN`中に減算。
* **CLEAR中**は**クリア時の残タイム比**から**5秒**かけ**100%までプログレスバーを補間**表示(演出のみ)。
---
## 11. 入力・操作
* **移動**:矢印 or **WASD**(同時押しは縦優先/斜め無効化)
* **描線トグル**:**Space**(押下で開始 / 離上で確定戻り)
* **リスタート**:**R**
* **ヘルプ表示**:**H**
* **フォーカス**:Canvasクリック/タップで付与(オーバーレイ案内あり)
---
## 12. HUD / UI
* **HUD表示**:取得率(小数1桁)、目標%、残機、レベル、敵数、時間(MM\:SS)、メッセージ
* **ボタン**:リスタート、ヘルプ
* **エラー表示**:画面上部固定バーに例外ハンドリング結果を通知
* **タップ案内**:「クリック(タップ)で操作開始」オーバーレイ
* **CLEAR/FAIL演出**:大文字オーバーレイ(CLEARは背景フェードイン付き)
* **RESPAWN表示**:画像エリアの外に**半透明黒+説明文**
* **TIMEバー**:画像エリアの外、上部中央(残比で色変化:緑/黄/赤)
---
## 13. 画像アセット
* **通常背景**:`img/backXX.jpg`
* **クリア背景**:`img/clearXX.jpg`(レベル番号は`01`〜`99`にゼロパディング)
* **読込失敗時**:**フォールバック背景**(グラデ+散布円)を生成して使用
* **スケーリング**:**cover相当**(中央合わせ、余白は切り)
---
## 14. レンダリング構成
1. **マスク**:`G_FILL`セルを白塗り(`maskC`)
2. **背景**:通常背景(`backC`)→ クリア背景(`clearC`)×マスク合成
3. **前景**:未確定線(`G_TEMP`矩形)、境界線(輪郭トレース)、プレイヤー(円+🙂)、敵(👾)
4. **オーバーレイ**:
* **CLEAR**:`clearC` をフェード合成 + 「CLEAR!!」
* **FAIL**:暗転+「GAME OVER」+再開ガイド
---
## 15. 取得率計算
* **カウント対象**:`G_FILL`セル数
* **分母**:外枠を除いた内側セル総数(`GW*GH - 枠周囲セル`)
* **表示**:小数1桁でHUDに反映
---
## 16. エラーハンドリング / 安全策
* **グローバルtry/catch**で**フレーム継続**。
* **MISS直後**は`__FRAME_ABORT__`例外を投げて**当該フレームを安全終了**(状態競合回避)。
* **画像失敗**は**フォールバック**で確実描画。
* **入力**は`keydown/keyup`を**window/document両方**にバインドし取りこぼしを低減。
* **フォーカス誘導**と**Space抑止**でスクロール等の誤動作防止。
---
## 17. レベル設計の既定
* **レベル番号**:1始まり、クリアでインクリメント無制限
* **敵数**と**速度**が逓増
* **背景画像**はレベル番号に応じて差し替え
---
## 18. 拡張ポイント(実装しやすい改修案)
* **難易度設定**:`GOAL`、`STAGE_TIME`、`lvEnemies`、`baseES`を外部化
* **当たり判定の可視化**:デバッグ層(敵円・TEMPセル)切替
* **パッド対応**:Gamepad APIで矢印/WASD相当入力
* **SE/BGM**:AudioContext(フォーカス取得時に初期化)
* **スコアリング**:残タイム・囲い面積・連続取得ボーナス
* **セーブ**:ローカルストレージで最高到達レベル/設定保存
* **画像先読み**:次レベル背景の事前読込
---
## 19. 配布・配置要件
* **単体HTML**で動作。画像を置く場合は同階層に`img/`フォルダを作成し、`back01.jpg` `clear01.jpg` 等を配置。
* サーバ不要(`file://`でも動作可)が、**ローカルのブラウザ制限**回避のため**HTTP配信推奨**。
* モバイルはタップでフォーカス後、外付けキーボードまたは仮想キーUIの追加で操作性向上。
---
## 20. 既知仕様(設計上の意図)
* 斜め移動は抑止(縦横1方向のみ)
* 自己交差は**直近4セル以内**のみ許容(それ以上は描線進行をブロック)
* ミス直後は**自動で線上復帰**し、プレイヤー操作で**任意の位置から再開**可能(ストレス低減)
* 画像が無くても**常に遊べる**(フォールバック描画)
---
## 21. UI文言(日本語)
* **ヘルプ(v38安定版)**:フェイルセーフ、フォーカス、フォールバック背景に関する簡易説明を内包
* **メッセージ**:`READY` / `CLEAR!` / `MISS! 線上を移動中… 任意キーで再開位置を確定` / `GAME OVER` / `R キー または クリックで リスタート`
---
## 22. テスト観点(抜粋)
* 画像無し/読み込み失敗時にゲーム継続できること
* Space押下・離上の境界ケース(起点が`FILL/EDGE`でない場合は開始不可)
* `RESPAWN`中は時間が進むが、**任意キー即復帰**が効くこと
* 取得率計算が外枠を除外していること
* 長時間放置(`IDLE_THRESH`超)時の敵挙動変化
* CLEAR中のプログレスバー補間(残タイム比→満タン)
---
## 23. ファイル構成(推奨)
```
/(本HTML)
/img/
back01.jpg
clear01.jpg
back02.jpg
clear02.jpg
...
```
コメント