🤖

【逃げる「点P」を捕まえろ!】Claude & Chat GPTコンビにシンプルなブラウザゲームを作ってもらった

に公開

はじめに

最近はものすごいAIブームですよね。
私自身も個人でエンジョイ勢として課金してモノづくりを楽しんでおります。
その一環で【Claudeくん】&【ChatGPT(通称:チャピ)】の2つを活用して、簡単なブラウザゲームを作ってみました。

こちらに設置してみましたので、よければ遊んでみてください。

https://catch-the-point-p.github.io/

⚠️ PCのみ対応です。スマートフォンでは正常に動きません。点Pがどこかいきます。

本編

ゲーム『逃げる「点P」を捕まえろ!』を作ってみた

さて、突然ですが皆さん。
学生時代の数学で「点P」に苦しめられた記憶はありませんか?
きっと皆様あるんじゃないでしょうか。

彼が動かなければ、地球温暖化に少子高齢化、あらゆる現象を全て食い止められていたことでしょう(過言)。彼はなぜ突然逃げ出すんでしょうね。いわゆる思春期、逃げたいお年頃ってやつだったんでしょうか...?🤔

ともかく、今回は点Pを動かすゲームを作ってみました。

作るまでの流れ

普段、2つClaude、ChatGPTを有料契約して併用していますが、概ね役割分担をさせています。
ChatGPT(実装もできるPMっぽい立ち位置)、Claude(ベテラン実装者の立ち位置で普段から色々お願いしています。

理由としては

  • ①ClaudeはProプランでもトークン量に上限があること(一定時間の制限あり)
  • ②ChatGPTが雑談ベースで仕様を決めやすく、また遊び心とのバランス感覚が人間寄りn印象であるため

なので今回もこの体制で行いました。

1. アイデアを出す

何はともあれ、まずはアイデアを出します。
「友人たちにAIの凄さを伝えたい!」からスタートしたので、完全ゼロベースでAIから作ってもらう想定で考えました。といっても思いつきなので、アイデア出すまでに僅か1分。カップ麺すら作れません!

2. 仕様をChatGPTと相談する

次にChatGPTと仕様を決めていきます。
最初の「ぼうけんの書」はこちらです。

逃げる点Pを10秒以内に捕まえるゲームを作って欲しい!クリアすると、レベルが上がって点Pの速度が上がる!最終的に移動距離を結果画面に出して!

これを仕様に落とし込んでみて!

俺たちの戦いはここからだ!

Chat GPTが仕様を考えてくれてこうなりました。

# 🎯 ゲーム仕様書:「逃げる点Pをつかまえろ!」

> レベル無制限 × 爽快マウスアクション × 究極の逃げP

---

## 🌟 概要

- プレイヤーは画面内を逃げ回る **点P** をクリックまたはタップで捕まえる
- 制限時間:1レベルあたり10秒
- 捕まえるたびに **レベルが無制限に上昇**
- 点Pの逃げ速度もレベルに応じて加速
- ゲーム終了時、**移動距離(px)と到達レベル**を表示

---

## 🎮 ゲームの流れ

1. ゲームスタート
2. 点Pがプレイヤーから逃げ続ける
3. 捕まえられたらレベルアップ → 再スタート
4. 10秒以内に捕まえられなければゲーム終了
5. 結果画面にスコアと移動距離を表示

---

## 🔢 ゲーム仕様

| 項目 | 内容 |
|------|------|
| フィールド | 点Pが動き回る画面エリア(例:500×500px) |
| 点Pの動き | プレイヤーのカーソル/タップ座標を避けるように移動 |
| 制限時間 | 各レベル10秒固定(カウントダウン表示あり) |
| 捕獲操作 | マウスクリックまたはタップ |
| 捕獲判定 | 点Pの中心から一定距離以内の操作でヒット |
| 移動制御 | requestAnimationFrame または setInterval |
| 移動速度 | 2 + level * 0.3 のように段階的上昇 |

---

## 📈 レベルアップ設計

- レベルは無制限(限界への挑戦)
- 捕まえるごとに +1、点Pの移動速度も加速
- プレイが続くほど **操作精度と反射神経が問われる**

```js
// 例:レベルによる速度計算
speed = 2 + level * 0.3;```
---

## 📏 点Pの移動距離計測

- 各フレームの移動距離 dx, dy を累積
- ゲーム終了時に合計pxとして表示

---

## 🖼 UI構成(想定)

| 要素 | 内容 |
|------|------|
| ゲームフィールド | 点Pが動く領域(中央配置、レスポンシブ対応推奨) |
| タイマー | 上部に10秒カウントダウン |
| レベル表示 | 現在のレベルを表示 |
| 結果画面 | 「あなたのレベル:X」「移動距離:YYYY px」など |

---

## 🛠 技術仕様

| 項目 | 内容 |
|------|------|
| ファイル構成 | index.html のみ(JS・CSS含む) |
| ライブラリ | なし(Vanilla JavaScript) |
| スタイル | シンプルで軽量なCSS。Tailwind等も使用可能 |
| 対応環境 | PC(マウス)・スマホ(タップ)両対応 |

---

## 💬 Claude等への依頼文サンプル

この仕様に沿って、**HTML1枚で遊べる「点Pをつかまえるゲーム」**を作成してください。  
- 点Pはマウスやタップ座標を避けて動く  
- 捕まえるとレベルアップ、速度も加速  
- レベルに上限はなく、ゲーム終了時にスコアと移動距離を表示してください  
- スタイルはシンプルでOK、PC・スマホ両対応を希望します

---

## 🧪 拡張アイデア(任意)

- 点Pに顔や表情をつけて「かわいさ」や「憎たらしさ」を演出
- スコアランキング機能(ローカルストレージなどで実装可)
- カーソルを点Pに近づけると「びっくりして逃げる」演出 など

---

## 📝 まとめ

「逃げる点Pをつかまえろ!」は、誰でも遊べるミニマルなルールながら、  
レベルが上がるほどに緊張感が増す、中毒性のあるゲームです。  
**HTML1枚で完結**する気軽さもあり、学習・実験・公開にも最適です。

大体イメージしていた通りでヨシッ⛑️😼

3. 実装

ということで、Claudeにバトンタッチします。

この仕様に沿って、HTML1枚で遊べる「点Pをつかまえるゲーム」を作ってください。
(上記の仕様をコピペ)

で実装をお願いしました。

この時点で出来上がってきたものは公開していませんが、この時点で「10秒以内に捕まえる」ゲームの骨格9割が完成しました。ただ、今よりデザインも近未来的で「The 生成AI」感の強いデザイン、音楽もなし、レベルが上がってもスピード以外の変化はなし、の状態でした。

4.コンテンツ性を追加+不具合調整

HTMLファイルができたのですが、不具合で動いていなかった箇所がありましたので手作業で修正を行いました。Claudeくんは長めのファイル1枚(特にペラ1のHTML)などを細々修正するのが非常に苦手です。修正が途中で途切れて「続けて」をさせた際に途中で止まった時の残骸が残ったり、修正をファイル1枚分丸ごと行おうとしたりします(そしてまた途中で止まる...)

こちらのプロンプトの問題なのでしょうか🤔

で、上記の修正をしてもらった後、音楽とレベルアップ時の特殊イベント等を追加で実装を依頼しました。

これらもふんわり依頼です。

こちらのゲーム、デザインをもっとポップにできるかな?
レトロなゲームの雰囲気で!あと、点Pが押しにくいから当たり判定を少し広げて!

素材は使わずブラウザで完結させたい。あと、ちゃんと最初はON/OFFさせておきたい。
音楽も作れたりするのかな?

レベル30を超えたら、(ワープではなく30の時点で壁に穴が開くアニメーションを入れる)指定した範囲外(元のエリアの2倍まで)に飛び出して範囲を動くようにしてください。

といった形で概要からニュアンスを組み上げもらって作りました。

5.Github Pagesに公開

ファイルができたので公開をして、おしまいです。
トータル1.5時間ほどで完成しました。

https://catch-the-point-p.github.io/

まとめ

昨今のAIの変革には、本当驚くばかりですよね。

私自身は作りたかったものがこれまでたくさんあった民なので、
それらを実現しやすくなり嬉しく思います。

反面、エンジニア職というところでは、
彼らとの共存が今後さらに必要とされてくるとも感じております。

と言いつつも、やっぱり単純に技術の進化が楽しくてワクワクしているところが大きいです。
各々、AIとの触れ合いを楽しんでいきましょう🏄


おまけ:ClaudeもQiitaに投稿する概要かいてくれました(一部調整あり)

HTML1枚で作る「逃げる点Pをつかまえろ!」- レトロゲーム風アクションゲーム

🎮 はじめに

昔懐かしいゲームボーイを彷彿とさせる、シンプルだけど奥深いアクションゲームを作りました!
HTML/CSS/JavaScriptのみで完結し、外部ライブラリ一切不要の軽量ゲームです。

🎵 ゲームの特徴

🎨 レトロなデザイン

  • ゲームボーイ風の4階調グリーンカラーパレット
  • ピクセルフォントと角ばったUI要素
  • レトロなボックスシャドウでドット絵風の立体感

🎶 本格的なチップチューン音楽

  • Web Audio APIで生成する8bit風BGM
  • メロディ+ベースラインの2トラック構成
  • 効果音(捕獲音、ゲームオーバー音、開始音)

🚀 段階的な難易度上昇

  • レベル無制限で永続的な挑戦
  • レベルアップで点Pの移動速度が向上
  • レベル30で特別なフィールド拡張イベント

🕳️ レベル30の壁破壊システム

  • 壁に穴が開くアニメーション演出
  • フィールドが1.2倍に拡張(500px → 600px)
  • より戦略的で高難易度なゲームプレイ

🛠️ 技術仕様

フロントエンド構成

- HTML5 (セマンティックマークアップ)
- CSS3 (アニメーション、レスポンシブ対応)
- Vanilla JavaScript (ES6+)
- Web Audio API (音声生成)

ゲームループ設計

// コアゲームループ
const animate = () => {
    if (!this.isGameRunning) return;
    
    this.movePointP();        // 点Pの移動計算
    this.updateUI();          // UI更新
    this.animationFrame = requestAnimationFrame(animate);
};

点Pの移動アルゴリズム

// マウスから逃げるベクトル計算
const dx = this.pointPPosition.x - this.mousePosition.x;
const dy = this.pointPPosition.y - this.mousePosition.y;
const distance = Math.sqrt(dx * dx + dy * dy);

// 正規化 + 速度適用 + ランダム要素
moveX = (dx / distance) * speed + (Math.random() - 0.5) * speed * 0.5;
moveY = (dy / distance) * speed + (Math.random() - 0.5) * speed * 0.5;

🎵 音声システムの実装

Web Audio APIによる音楽生成

// チップチューン風メロディの作成
playTone(frequency, duration, startTime, waveType = 'square') {
    const oscillator = this.audioContext.createOscillator();
    const envelope = this.audioContext.createGain();
    
    oscillator.type = waveType;  // 矩形波で8bit感
    oscillator.frequency.setValueAtTime(frequency, startTime);
    
    // エンベロープでアタック・リリース制御
    envelope.gain.setValueAtTime(0, startTime);
    envelope.gain.linearRampToValueAtTime(volume, startTime + 0.01);
    envelope.gain.exponentialRampToValueAtTime(0.01, startTime + duration);
}

BGMループシステム

// 8秒周期でのメロディ+ベース同期再生
const melody = [
    {freq: 523, dur: 0.25}, {freq: 659, dur: 0.25}, // ドミ
    {freq: 784, dur: 0.25}, {freq: 659, dur: 0.25}, // ソミ
    // ... メロディライン継続
];

const bassLine = [
    {freq: 131, dur: 0.5}, {freq: 0, dur: 0.5},     // Cベース + 休符
    // ... ベースライン継続
];

🎯 ゲーム仕様詳細

基本ルール

項目 内容
制限時間 各レベル10秒固定
操作方法 クリック/タップで捕獲
当たり判定 点P中心から半径50px
速度上昇 2 + level * 0.3 px/frame
移動距離 1px = 1cm換算で表示

レベル30イベント

expandField() {
    // 1. 警告メッセージ表示
    warning.classList.add('show');
    
    // 2. ゲーム一時停止
    this.isGameRunning = false;
    
    // 3. 壁の穴を順次開く
    holes.forEach((holeId, index) => {
        setTimeout(() => {
            document.getElementById(holeId).classList.add('active');
        }, index * 200);
    });
    
    // 4. フィールド拡張
    this.gameField.classList.add('expanded');
    this.isFieldExpanded = true;
}

📱 レスポンシブ対応

デバイス別最適化

@media (max-width: 600px) {
    .game-field {
        width: 350px;
        height: 350px;
    }
    
    .ui-bar {
        flex-direction: column;
        gap: 10px;
    }
    
    .sound-toggle {
        position: relative;
        margin-bottom: 10px;
    }
}

🔒 セキュリティ考慮事項

XSS対策

// innerHTML使用回避、textContentで安全な文字列設定
document.getElementById('finalLevel').textContent = this.level;
document.getElementById('totalDistance').textContent = distanceText;

外部依存ゼロ

  • 外部CDN不使用
  • 完全自己完結型
  • オフライン動作可能

🚀 デプロイ方法

GitHub Pages

  1. リポジトリ作成
  2. index.html としてアップロード
  3. Settings > Pages で公開

必要なファイル

プロジェクトフォルダ/
├── index.html (ゲーム本体)
└── README.md (説明)

💡 技術的な学び

1. ゲームループ最適化

requestAnimationFrameを使用することで、ブラウザのリフレッシュレートに同期した滑らかな60FPSアニメーションを実現。

2. 座標変換の重要性

フィールド拡張時の表示サイズと論理サイズの違いを座標変換で解決。

3. Web Audio APIの活用

外部音源ファイル不要で、リアルタイム音楽生成による軽量化。

4. CSS アニメーションとJSの協調

CSSトランジション + JSイベント制御で複雑なアニメーション演出。

🎉 まとめ

HTML1枚という制約の中で、以下を実現できました:

  • 🎮 本格的なゲーム体験
  • 🎵 リアルタイム音楽生成
  • 🎨 レトロで美しいデザイン
  • 📱 マルチデバイス対応
  • 🔒 セキュアな実装

シンプルな技術スタックでも、工夫次第で魅力的なWebゲームが作れることを実証できたと思います!


最高レベルはいくつまで到達できるでしょうか?ぜひ挑戦してみてください!🎯

タグ

#JavaScript #HTML5 #CSS3 #WebAudioAPI #ゲーム開発 #レトロゲーム #Webゲーム

Discussion