ちいかわの下剋上オンラインを作ろうとしたら別ゲームができた【AI生成ゲーム実験 Vol.3】 誰でも作れるプロンプトサンプルとソースコードを公開中

2025年7月10日木曜日

オリジナルゲーム ゲーム開発 ちいかわ プロンプト 無料ゲーム

t f B! P L

 こんにちは、AM0500です。

今回は、ちいかわに出てくる「下剋上オンライン」をイメージして作ろうとしたらまったく別のゲームができたお話です。ちいかわが好きでいつかあれをゲーム化して公開してみたいと思っていたのですが、まずはAIだとどんなのを作ってくれるのだろうと思い試してみたところ・・・

🔗 実際にプレイしてみる

▼ ブラウザでそのまま遊べます(PC推奨):
👉 ちいかわの下剋上オンラインを作ろうとしたら別ゲームになってしまったゲーム


👉 使用したAI Claude(claude 4 sonnet)はこちら
  ※英語でとっつきにくく見えますが、やり取りは日本語でできます。

誰でも作れる作成用プロンプトとコピペで遊べるhtmlソースコードを公開していますので、よろしければご利用ください。


🎮 ゲーム画面(スクリーンショット)


画像
画像

📝 一言コメント

ナガノ先生の作品が好きで、ちいかわももちろん大好きで、作中に出てくる「下剋上オンライン」というゲームを再現したら面白いかなと思ってAIに指示してみました。
しかし、AIは流石にちいかわの下剋上オンラインを認識できず、現代版の成り上がりゲームが作成されました。今後、プロンプトを変更して再挑戦予定です。果たして下剋上オンラインは完成するのか?
Bloggerに作品を公開しているのですが、仕様により「¥」や「。」「!」などの文字が使えず、一部の文字を削ったバージョンを公開しています。
オリジナルのソースはこちらのNoteの内容を参照ください。



🧠 使用したClaudeへのプロンプト

以下のような指示だけで、今回のゲームが生成されました。

ちいかわで出てくる「下剋上オンライン」みたいなゲームは作れる?

さすがにちいかわで出てくる~は認識されず「下剋上オンライン」という響きから、オリジナルのゲームを作ってくれました。


🕹️ Claudeが返してくれた説明文

ちいかわの「下剋上オンライン」を再現したゲームを作成しました!
ゲームの特徴:

🎯 基本システム
フリーターから社長まで11段階の職業階層
「働く」と「上司に挑戦」の2つのメインアクション
レベル、経験値、お金、体力の管理

⚡ 働くシステム
7種類のランダムイベント(褒められたり、ミスしたり)
職業レベルに応じた基本給与
体力消費と経験値獲得

🔥 挑戦システム
体力30消費で上司に挑戦
レベルと経験値に基づく成功確率
成功すれば昇進、失敗すれば降格の可能性

📊 ハラハラ要素
成功確率は30%~80%の間で変動
降格リスクがあるスリリングな挑戦
体力管理が重要な戦略要素

🎮 ゲームの流れ
働いて経験値とお金を貯める
体力が溜まったら上司に挑戦
成功すれば昇進、失敗すれば降格リスク
社長を目指して頑張る!

原作のハラハラドキドキ感を再現しつつ、長期的な成長要素も盛り込みました。体力は自動回復するので、気長に社長を目指してください!


💡 ソースコード(HTML)

下記がhtmlの中身になります。ご自由にご利用ください。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>下剋上オンライン</title>
    <style>
        body {
            margin: 0;
            padding: 20px;
            background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
            font-family: 'Meiryo', sans-serif;
            color: white;
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        
        .game-container {
            background: rgba(0, 0, 0, 0.8);
            border-radius: 20px;
            padding: 30px;
            max-width: 800px;
            width: 100%;
            border: 2px solid #34495e;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
        }
        
        .game-title {
            text-align: center;
            font-size: 28px;
            font-weight: bold;
            margin-bottom: 20px;
            color: #e74c3c;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
        }
        
        .status-bar {
            display: flex;
            justify-content: space-between;
            margin-bottom: 20px;
            padding: 15px;
            background: rgba(52, 73, 94, 0.5);
            border-radius: 10px;
        }
        
        .status-item {
            text-align: center;
        }
        
        .status-label {
            font-size: 12px;
            color: #bdc3c7;
            margin-bottom: 5px;
        }
        
        .status-value {
            font-size: 18px;
            font-weight: bold;
            color: #ecf0f1;
        }
        
        .current-job {
            text-align: center;
            margin-bottom: 30px;
            padding: 20px;
            background: linear-gradient(135deg, #8e44ad, #9b59b6);
            border-radius: 15px;
            box-shadow: 0 5px 15px rgba(142, 68, 173, 0.3);
        }
        
        .job-title {
            font-size: 24px;
            font-weight: bold;
            margin-bottom: 10px;
        }
        
        .job-description {
            font-size: 14px;
            color: #f8f9fa;
            opacity: 0.9;
        }
        
        .actions {
            display: flex;
            gap: 15px;
            margin-bottom: 30px;
        }
        
        .action-btn {
            flex: 1;
            padding: 15px 20px;
            font-size: 16px;
            font-weight: bold;
            border: none;
            border-radius: 10px;
            cursor: pointer;
            transition: all 0.3s;
            color: white;
        }
        
        .work-btn {
            background: linear-gradient(135deg, #27ae60, #2ecc71);
            box-shadow: 0 4px 15px rgba(46, 204, 113, 0.3);
        }
        
        .work-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(46, 204, 113, 0.4);
        }
        
        .challenge-btn {
            background: linear-gradient(135deg, #e74c3c, #c0392b);
            box-shadow: 0 4px 15px rgba(231, 76, 60, 0.3);
        }
        
        .challenge-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(231, 76, 60, 0.4);
        }
        
        .challenge-btn:disabled {
            background: #7f8c8d;
            cursor: not-allowed;
            transform: none;
            box-shadow: none;
        }
        
        .log {
            background: rgba(52, 73, 94, 0.3);
            border-radius: 10px;
            padding: 20px;
            max-height: 200px;
            overflow-y: auto;
            margin-bottom: 20px;
        }
        
        .log-entry {
            margin-bottom: 10px;
            padding: 8px 12px;
            border-radius: 5px;
            font-size: 14px;
            animation: slideIn 0.3s ease-out;
        }
        
        .log-success {
            background: rgba(46, 204, 113, 0.2);
            border-left: 4px solid #2ecc71;
        }
        
        .log-failure {
            background: rgba(231, 76, 60, 0.2);
            border-left: 4px solid #e74c3c;
        }
        
        .log-promotion {
            background: rgba(241, 196, 15, 0.2);
            border-left: 4px solid #f1c40f;
            font-weight: bold;
        }
        
        .log-demotion {
            background: rgba(155, 89, 182, 0.2);
            border-left: 4px solid #9b59b6;
        }
        
        @keyframes slideIn {
            from {
                opacity: 0;
                transform: translateX(-20px);
            }
            to {
                opacity: 1;
                transform: translateX(0);
            }
        }
        
        .challenge-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.8);
            display: none;
            justify-content: center;
            align-items: center;
            z-index: 1000;
        }
        
        .modal-content {
            background: #2c3e50;
            padding: 30px;
            border-radius: 15px;
            text-align: center;
            max-width: 400px;
            width: 90%;
            border: 2px solid #34495e;
        }
        
        .modal-title {
            font-size: 20px;
            font-weight: bold;
            margin-bottom: 20px;
            color: #e74c3c;
        }
        
        .modal-text {
            margin-bottom: 20px;
            line-height: 1.6;
        }
        
        .modal-btn {
            padding: 10px 20px;
            margin: 0 10px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 16px;
            font-weight: bold;
            color: white;
        }
        
        .modal-accept {
            background: linear-gradient(135deg, #e74c3c, #c0392b);
        }
        
        .modal-decline {
            background: linear-gradient(135deg, #7f8c8d, #95a5a6);
        }
        
        .stats {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 15px;
            margin-top: 20px;
        }
        
        .stat-card {
            background: rgba(52, 73, 94, 0.5);
            padding: 15px;
            border-radius: 10px;
            text-align: center;
        }
        
        .stat-title {
            font-size: 12px;
            color: #bdc3c7;
            margin-bottom: 5px;
        }
        
        .stat-value {
            font-size: 18px;
            font-weight: bold;
            color: #ecf0f1;
        }
    </style>
</head>
<body>
    <div class="game-container">
        <div class="game-title">下剋上オンライン</div>
        
        <div class="status-bar">
            <div class="status-item">
                <div class="status-label">レベル</div>
                <div class="status-value" id="level">1</div>
            </div>
            <div class="status-item">
                <div class="status-label">経験値</div>
                <div class="status-value" id="exp">0</div>
            </div>
            <div class="status-item">
                <div class="status-label">お金</div>
                <div class="status-value" id="money"1000</div>
            </div>
            <div class="status-item">
                <div class="status-label">体力</div>
                <div class="status-value" id="stamina">100</div>
            </div>
        </div>
        
        <div class="current-job" id="currentJob">
            <div class="job-title" id="jobTitle">フリーター</div>
            <div class="job-description" id="jobDescription">日雇いのアルバイトをしています</div>
        </div>
        
        <div class="actions">
            <button class="action-btn work-btn" onclick="work()">働く</button>
            <button class="action-btn challenge-btn" id="challengeBtn" onclick="showChallenge()">上司に挑戦</button>
        </div>
        
        <div class="log" id="gameLog"></div>
        
        <div class="stats">
            <div class="stat-card">
                <div class="stat-title">成功回数</div>
                <div class="stat-value" id="successCount">0</div>
            </div>
            <div class="stat-card">
                <div class="stat-title">失敗回数</div>
                <div class="stat-value" id="failureCount">0</div>
            </div>
            <div class="stat-card">
                <div class="stat-title">昇進回数</div>
                <div class="stat-value" id="promotionCount">0</div>
            </div>
            <div class="stat-card">
                <div class="stat-title">降格回数</div>
                <div class="stat-value" id="demotionCount">0</div>
            </div>
        </div>
    </div>
    
    <div class="challenge-modal" id="challengeModal">
        <div class="modal-content">
            <div class="modal-title">上司への挑戦</div>
            <div class="modal-text" id="challengeText">
                本当に上司に挑戦しますか?<br>
                成功すれば昇進、失敗すれば降格の可能性があります。
            </div>
            <button class="modal-btn modal-accept" onclick="challenge()">挑戦する</button>
            <button class="modal-btn modal-decline" onclick="hideChallenge()">やめる</button>
        </div>
    </div>

    <script>
        // ゲーム状態
        let gameState = {
            level: 1,
            exp: 0,
            money: 1000,
            stamina: 100,
            jobLevel: 0,
            successCount: 0,
            failureCount: 0,
            promotionCount: 0,
            demotionCount: 0,
            lastChallengeTime: 0
        };

        // 職業データ
        const jobs = [
            { title: "フリーター", description: "日雇いのアルバイトをしています", salary: 100, challengeReq: 0 },
            { title: "アルバイト", description: "コンビニでバイトしています", salary: 150, challengeReq: 50 },
            { title: "派遣社員", description: "派遣会社で働いています", salary: 200, challengeReq: 100 },
            { title: "契約社員", description: "契約社員として働いています", salary: 300, challengeReq: 200 },
            { title: "正社員", description: "正社員として働いています", salary: 500, challengeReq: 350 },
            { title: "主任", description: "チームのリーダーです", salary: 750, challengeReq: 500 },
            { title: "係長", description: "係をまとめています", salary: 1000, challengeReq: 750 },
            { title: "課長", description: "課の責任者です", salary: 1500, challengeReq: 1000 },
            { title: "部長", description: "部門の責任者です", salary: 2000, challengeReq: 1500 },
            { title: "取締役", description: "会社の役員です", salary: 3000, challengeReq: 2500 },
            { title: "社長", description: "会社のトップです!", salary: 5000, challengeReq: 4000 }
        ];

        // ランダムイベント
        const workEvents = [
            { message: "真面目に働きました", exp: 10, money: 0, stamina: -10 },
            { message: "残業をしました", exp: 15, money: 50, stamina: -20 },
            { message: "上司に褒められました", exp: 20, money: 100, stamina: -5 },
            { message: "ミスをしてしまいました", exp: 5, money: -50, stamina: -15 },
            { message: "新しいスキルを覚えました", exp: 25, money: 0, stamina: -10 },
            { message: "同僚と仲良くなりました", exp: 12, money: 0, stamina: -8 },
            { message: "お客さんに感謝されました", exp: 18, money: 80, stamina: -12 }
        ];

        // UI更新
        function updateUI() {
            document.getElementById('level').textContent = gameState.level;
            document.getElementById('exp').textContent = gameState.exp;
            document.getElementById('money').textContent = '¥' + gameState.money;
            document.getElementById('stamina').textContent = gameState.stamina;
            document.getElementById('successCount').textContent = gameState.successCount;
            document.getElementById('failureCount').textContent = gameState.failureCount;
            document.getElementById('promotionCount').textContent = gameState.promotionCount;
            document.getElementById('demotionCount').textContent = gameState.demotionCount;
            
            const currentJob = jobs[gameState.jobLevel];
            document.getElementById('jobTitle').textContent = currentJob.title;
            document.getElementById('jobDescription').textContent = currentJob.description;
            
            // 挑戦ボタンの状態
            const challengeBtn = document.getElementById('challengeBtn');
            const canChallenge = gameState.stamina >= 30 && gameState.jobLevel < jobs.length - 1;
            challengeBtn.disabled = !canChallenge;
            
            if (gameState.jobLevel >= jobs.length - 1) {
                challengeBtn.textContent = "最高位到達";
            } else {
                challengeBtn.textContent = "上司に挑戦";
            }
        }

        // ログを追加
        function addLog(message, type = 'success') {
            const logContainer = document.getElementById('gameLog');
            const logEntry = document.createElement('div');
            logEntry.className = `log-entry log-${type}`;
            logEntry.textContent = message;
            
            logContainer.insertBefore(logEntry, logContainer.firstChild);
            
            // ログが多くなったら古いものを削除
            while (logContainer.children.length > 10) {
                logContainer.removeChild(logContainer.lastChild);
            }
        }

        // 働く
        function work() {
            if (gameState.stamina < 10) {
                addLog("体力不足で働けません", "failure");
                return;
            }
            
            const currentJob = jobs[gameState.jobLevel];
            const event = workEvents[Math.floor(Math.random() * workEvents.length)];
            
            // 基本報酬
            gameState.money += currentJob.salary;
            gameState.exp += event.exp;
            gameState.stamina = Math.max(0, gameState.stamina + event.stamina);
            
            // イベント報酬
            if (event.money > 0) {
                gameState.money += event.money;
                addLog(`${event.message} (+${event.exp}EXP, +¥${currentJob.salary + event.money})`, "success");
            } else if (event.money < 0) {
                gameState.money = Math.max(0, gameState.money + event.money);
                addLog(`${event.message} (+${event.exp}EXP, ${event.money}円)`, "failure");
            } else {
                addLog(`${event.message} (+${event.exp}EXP, +¥${currentJob.salary})`, "success");
            }
            
            gameState.successCount++;
            
            // レベルアップチェック
            const expNeeded = gameState.level * 100;
            if (gameState.exp >= expNeeded) {
                gameState.level++;
                gameState.exp -= expNeeded;
                gameState.stamina = Math.min(100, gameState.stamina + 20);
                addLog(`レベルアップ! レベル${gameState.level}になりました`, "promotion");
            }
            
            // 体力回復(少し)
            gameState.stamina = Math.min(100, gameState.stamina + 2);
            
            updateUI();
        }

        // 挑戦モーダルを表示
        function showChallenge() {
            if (gameState.stamina < 30) {
                addLog("体力不足で挑戦できません", "failure");
                return;
            }
            
            if (gameState.jobLevel >= jobs.length - 1) {
                addLog("既に最高位に到達しています", "failure");
                return;
            }
            
            const nextJob = jobs[gameState.jobLevel + 1];
            const challengeText = document.getElementById('challengeText');
            challengeText.innerHTML = `
                ${nextJob.title}への昇進を目指しますか?<br>
                必要体力: 30<br>
                成功すれば昇進、失敗すれば降格の可能性があります。
            `;
            
            document.getElementById('challengeModal').style.display = 'flex';
        }

        // 挑戦モーダルを非表示
        function hideChallenge() {
            document.getElementById('challengeModal').style.display = 'none';
        }

        // 挑戦実行
        function challenge() {
            hideChallenge();
            
            gameState.stamina -= 30;
            
            // 成功確率計算(レベルと経験値に基づく)
            const baseSuccessRate = 0.3;
            const levelBonus = gameState.level * 0.05;
            const expBonus = Math.min(gameState.exp / 1000, 0.2);
            const successRate = Math.min(baseSuccessRate + levelBonus + expBonus, 0.8);
            
            const success = Math.random() < successRate;
            
            if (success) {
                // 昇進
                gameState.jobLevel++;
                gameState.promotionCount++;
                gameState.exp += 50;
                gameState.money += 500;
                
                const newJob = jobs[gameState.jobLevel];
                addLog(`昇進しました! ${newJob.title}になりました!`, "promotion");
                
                if (gameState.jobLevel >= jobs.length - 1) {
                    addLog("おめでとうございます!社長に到達しました!", "promotion");
                }
            } else {
                // 失敗
                gameState.failureCount++;
                
                // 降格の可能性
                if (gameState.jobLevel > 0 && Math.random() < 0.4) {
                    gameState.jobLevel--;
                    gameState.demotionCount++;
                    const newJob = jobs[gameState.jobLevel];
                    addLog(`降格してしまいました... ${newJob.title}になりました`, "demotion");
                } else {
                    addLog("挑戦に失敗しました。次回頑張りましょう", "failure");
                }
                
                gameState.money = Math.max(0, gameState.money - 200);
            }
            
            updateUI();
        }

        // 自動体力回復
        setInterval(() => {
            if (gameState.stamina < 100) {
                gameState.stamina = Math.min(100, gameState.stamina + 1);
                updateUI();
            }
        }, 3000);

        // ゲーム開始
        addLog("下剋上オンラインへようこそ!頑張って社長を目指しましょう!", "promotion");
        updateUI();
    </script>
</body>
</html>

🔔 補足・注意事項

このコードや説明は、Claudeのバージョンや環境によって出力内容が異なる可能性があります。
同じ命令をしても、まったく違うコードが返ってくることもあるので、再現性は参考程度にご覧ください。


🔔 リンク

👉 AM0500 作品一覧
👉 AM0500 GAME LAB

このブログを検索

アクションゲームメーカーでタイトル画面からゲーム本編へ切り替える基本手順(画面遷移のやり方)

 こんにちは、AM0500です。 今回は、アクションゲームメーカー(AGM)で タイトル画面から実際のゲームシーンへ移動させる手順 をまとめます。 AGMでは、シーンの移動を個別のプログラムで書くのではなく、 「SceneTransition」という専用の画面 で一括管理します。...

最近の投稿

記事まとめ

自己紹介

自分の写真
飼い猫のモイちゃんに朝5時に起こされる生活が続いたのでAM0500と名付けました。モイちゃんへの愛でゲーム制作にも挑戦しはじめて、素人ながらも、モイちゃんを主役にしたゲームを作り上げた時の喜びは忘れられません。そこから趣味でゲーム開発を始めました。勉強中の身ですがよろしくお願いします。

QooQ