🔬 AI発明ギャラリー kizu 脱出ゲーム
🔒 サンドボックス内で実行中 ⛶ 全画面で遊ぶ
HTML / CSS / JS
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Prison Escape - 牢獄からの脱出</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Special+Elite&display=swap');

        body {
            background-color: #0a0a0a;
            color: #d1d1d1;
            font-family: 'Special+Elite', cursive, serif;
            margin: 0;
            overflow: hidden;
            height: 100vh;
            display: flex;
            flex-direction: column;
        }

        #game-container {
            position: relative;
            width: 100%;
            max-width: 800px;
            height: 500px;
            margin: auto;
            background: #1a1a1a;
            border: 4px solid #333;
            overflow: hidden;
            box-shadow: 0 0 50px rgba(0,0,0,0.8);
        }

        .scene {
            position: absolute;
            width: 100%;
            height: 100%;
            display: none;
            background-size: cover;
            background-position: center;
        }

        .scene.active {
            display: block;
        }

        .clickable {
            position: absolute;
            cursor: pointer;
            transition: background 0.3s;
        }

        .clickable:hover {
            background: rgba(255, 255, 255, 0.1);
            border: 1px dashed rgba(255, 255, 255, 0.3);
        }

        #inventory {
            width: 100%;
            max-width: 800px;
            height: 80px;
            margin: 10px auto;
            background: #222;
            border: 2px solid #444;
            display: flex;
            align-items: center;
            padding: 0 10px;
            gap: 10px;
        }

        .inv-slot {
            width: 60px;
            height: 60px;
            background: #333;
            border: 1px solid #555;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 24px;
            cursor: pointer;
        }

        .inv-slot.selected {
            border-color: #eab308;
            box-shadow: inset 0 0 10px rgba(234, 179, 8, 0.5);
        }

        #message-box {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            width: 90%;
            background: rgba(0, 0, 0, 0.8);
            border: 1px solid #eab308;
            padding: 15px;
            text-align: center;
            pointer-events: none;
            opacity: 0;
            transition: opacity 0.3s;
            z-index: 100;
        }

        #message-box.active {
            opacity: 1;
        }

        .overlay {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.85);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 200;
            display: none;
        }

        /* Textures & Effects */
        .wall-texture {
            background-color: #1a1a1a;
            background-image: linear-gradient(315deg, #111 25%, transparent 25%), linear-gradient(45deg, #111 25%, transparent 25%);
            background-size: 40px 40px;
        }
        .hallway-texture { background: linear-gradient(to bottom, #222, #000); }
        .outdoor-texture { background: linear-gradient(to top, #050505, #1a1a2e); }
        .iron-bars { background: repeating-linear-gradient(90deg, #333, #333 10px, transparent 10px, transparent 40px); }

        .laser {
            position: absolute;
            background: rgba(255, 0, 0, 0.6);
            box-shadow: 0 0 10px red;
            pointer-events: none;
        }

        /* Icons */
        .key-icon::after { content: '🔑'; }
        .hammer-icon::after { content: '🔨'; }
        .paper-icon::after { content: '📜'; }
        .screwdriver-icon::after { content: '🪛'; }
        .pliers-icon::after { content: '✂️'; }

        .stage-indicator {
            position: absolute;
            top: 10px;
            right: 10px;
            color: #666;
            font-size: 0.8rem;
        }
    </style>
</head>
<body>

    <div class="p-4 text-center">
        <h1 class="text-3xl font-bold text-gray-500 uppercase tracking-widest">Prison Escape</h1>
        <p id="sub-title" class="text-sm text-gray-600 mt-1">Stage 1: The Dark Cell</p>
    </div>

    <div id="game-container">
        <!-- Stage 1: The Cell -->
        <div id="scene-1" class="scene active wall-texture">
            <div class="stage-indicator">Stage 1</div>
            <div id="obj-door-1" class="clickable iron-bars" style="top: 50px; left: 350px; width: 100px; height: 350px;" onclick="interact('door1')"></div>
            <div id="obj-bed" class="clickable bg-yellow-900/20" style="bottom: 20px; left: 50px; width: 200px; height: 100px; border-radius: 50px 50px 0 0;" onclick="interact('bed')">
                <div class="text-center mt-8 text-xs text-yellow-800">藁の山</div>
            </div>
            <div id="obj-brick" class="clickable bg-gray-800" style="top: 200px; right: 100px; width: 60px; height: 30px; border: 1px solid #444;" onclick="interact('brick')"></div>
            <div id="obj-wall" class="clickable" style="top: 80px; left: 100px; width: 120px; height: 80px;" onclick="interact('wall')">
                <span class="text-gray-700 text-[10px] select-none">|||| |||| ||</span>
            </div>
        </div>

        <!-- Stage 2: The Hallway -->
        <div id="scene-2" class="scene hallway-texture">
            <div class="stage-indicator">Stage 2</div>
            <div id="obj-exit-2" class="clickable bg-gray-900 border-l-4 border-gray-700" style="top: 50px; right: 0; width: 80px; height: 400px;" onclick="interact('exit2')">
                <div class="text-red-900 text-xs rotate-90 mt-20">LOCKED</div>
            </div>
            <div id="obj-toolbox" class="clickable bg-blue-900/20" style="bottom: 50px; left: 150px; width: 100px; height: 60px; border: 2px solid #334;" onclick="interact('toolbox')">
                <div class="text-center text-[10px] text-blue-800">工具箱</div>
            </div>
            <div id="obj-panel" class="clickable bg-gray-700" style="top: 150px; left: 400px; width: 80px; height: 100px; border: 2px solid #222;" onclick="interact('panel')">
                <div class="flex flex-col items-center justify-center h-full gap-2">
                    <div id="panel-light" class="w-4 h-4 rounded-full bg-red-600 animate-pulse"></div>
                    <div class="w-10 h-1 bg-black"></div>
                </div>
            </div>
        </div>

        <!-- Stage 3: The Perimeter -->
        <div id="scene-3" class="scene outdoor-texture">
            <div class="stage-indicator">Stage 3</div>
            <!-- Laser Security -->
            <div id="laser-1" class="laser" style="top: 100px; left: 0; width: 100%; height: 2px;"></div>
            <div id="laser-2" class="laser" style="top: 250px; left: 0; width: 100%; height: 2px;"></div>
            <div id="laser-3" class="laser" style="top: 400px; left: 0; width: 100%; height: 2px;"></div>

            <!-- Guard Box -->
            <div id="obj-guardbox" class="clickable bg-gray-800" style="bottom: 20px; right: 50px; width: 120px; height: 150px; border: 2px solid #555;" onclick="interact('guardbox')">
                <div class="text-center text-[10px] text-gray-400 mt-2">警備用電源</div>
            </div>

            <!-- Wire Box -->
            <div id="obj-wirebox" class="clickable" style="top: 300px; left: 50px; width: 60px; height: 60px; border: 1px dashed #444;" onclick="interact('wirebox')">
                <div class="text-[8px] text-red-800 text-center">高電圧注意</div>
            </div>

            <!-- Final Gate -->
            <div id="obj-gate" class="clickable bg-black/40 border-4 border-gray-600" style="top: 50px; left: 300px; width: 200px; height: 400px;" onclick="interact('gate')">
                <div class="flex items-center justify-center h-full">
                    <div class="w-12 h-12 rounded-full border-4 border-red-900 flex items-center justify-center">
                        <div id="gate-button" class="w-8 h-8 rounded-full bg-red-900"></div>
                    </div>
                </div>
            </div>
        </div>

        <div id="message-box"></div>

        <!-- Result Overlay -->
        <div id="overlay-end" class="overlay">
            <h2 class="text-4xl text-yellow-500 mb-4 font-bold">完全脱出!</h2>
            <p class="mb-2 text-xl">あなたはついに自由を手に入れた...</p>
            <p class="mb-8 text-gray-500 italic text-sm">Freedom is yours. End of Chapter 1.</p>
            <button onclick="location.reload()" class="bg-yellow-900/40 hover:bg-yellow-800/60 text-yellow-200 px-8 py-3 border border-yellow-600 transition-all">最初からやり直す</button>
        </div>
    </div>

    <div id="inventory">
        <div class="text-xs text-gray-500 mr-2 uppercase">道具箱</div>
        <div id="slot-1" class="inv-slot" onclick="selectItem(0)"></div>
        <div id="slot-2" class="inv-slot" onclick="selectItem(1)"></div>
        <div id="slot-3" class="inv-slot" onclick="selectItem(2)"></div>
        <div id="slot-4" class="inv-slot" onclick="selectItem(3)"></div>
    </div>

    <script>
        const state = {
            currentStage: 1,
            inventory: [],
            selectedItem: null,
            flags: {
                // Stage 1
                bedSearched: false,
                brickBroken: false,
                hasCode: false,
                // Stage 2
                keyFound2: false,
                toolboxOpened: false,
                panelFixed: false,
                doorPowerOn: false,
                // Stage 3
                pliersFound: false,
                lasersOff: false,
                gateUnlocked: false
            }
        };

        const messages = {
            // Stage 1
            bed_find: "藁の中から「鍵」と「ハンマー」を見つけた!",
            brick_need_tool: "レンガが浮いている。叩けば壊せそうだ。",
            brick_break: "ハンマーで叩き壊した。中に「メモ」がある。",
            wall_clue: "メモをかざすと数字が読める...『3 8 2 1』",
            door_locked: "頑丈な扉だ。鍵と4桁の番号が必要らしい。",
            door_unlock: "ガチャリ! 牢獄の扉が開いた。外へ出よう。",
            
            // Stage 2
            hallway_intro: "廊下に出た。出口の電子ロックが赤く光っている。",
            toolbox_locked: "工具箱に鍵がかかっている。",
            toolbox_key_hint: "工具箱の裏を調べると、予備の「鍵」を見つけた!",
            toolbox_open: "鍵が合った!中から「ドライバー」を手に入れた。",
            panel_fixed: "ドライバーで配電盤を修理した。電子ロックの電力が回復した!",
            exit2_locked: "電子ロックがまだ赤色だ。電力を通さなければ。",
            exit2_success: "電子ロック解除。さらに先へ進む...",

            // Stage 3
            stage3_intro: "外だ!だがレーザーセキュリティが作動している。触れると警報が鳴るだろう。",
            guardbox_find: "警備ボックスの隙間に「ペンチ」が挟まっているのを見つけた!",
            wirebox_danger: "ここがレーザーの制御盤か。素手では危ない。",
            wirebox_cut: "ペンチで赤い配線を切断した!レーザーが消えた。",
            gate_locked: "門のボタンが反応しない。レーザーを先に止める必要がある。",
            gate_final: "門がゆっくりと開いていく... 自由だ!"
        };

        function showMessage(text) {
            const box = document.getElementById('message-box');
            box.innerText = text;
            box.classList.add('active');
            setTimeout(() => {
                box.classList.remove('active');
            }, 3000);
        }

        function switchScene(stage) {
            document.querySelectorAll('.scene').forEach(s => s.classList.remove('active'));
            const nextScene = document.getElementById(`scene-${stage}`);
            if (nextScene) {
                nextScene.classList.add('active');
                state.currentStage = stage;
                
                if (stage === 2) {
                    document.getElementById('sub-title').innerText = "Stage 2: The Silent Hallway";
                    showMessage(messages.hallway_intro);
                } else if (stage === 3) {
                    document.getElementById('sub-title').innerText = "Stage 3: The Final Gate";
                    showMessage(messages.stage3_intro);
                }
            }
        }

        function updateInventoryUI() {
            for (let i = 0; i < 4; i++) {
                const slot = document.getElementById(`slot-${i+1}`);
                if (!slot) continue;
                slot.innerHTML = '';
                slot.className = 'inv-slot';
                
                if (state.inventory[i]) {
                    const item = state.inventory[i];
                    const icon = document.createElement('span');
                    if (item === 'key') icon.className = 'key-icon';
                    if (item === 'hammer') icon.className = 'hammer-icon';
                    if (item === 'paper') icon.className = 'paper-icon';
                    if (item === 'screwdriver') icon.className = 'screwdriver-icon';
                    if (item === 'pliers') icon.className = 'pliers-icon';
                    slot.appendChild(icon);
                    
                    if (state.selectedItem === i) {
                        slot.classList.add('selected');
                    }
                }
            }
        }

        function addItem(item) {
            if (!state.inventory.includes(item)) {
                state.inventory.push(item);
                updateInventoryUI();
            }
        }

        function removeItem(item) {
            state.inventory = state.inventory.filter(i => i !== item);
            state.selectedItem = null;
            updateInventoryUI();
        }

        function selectItem(index) {
            if (state.inventory[index]) {
                state.selectedItem = state.selectedItem === index ? null : index;
                updateInventoryUI();
            }
        }

        function interact(obj) {
            const selected = state.inventory[state.selectedItem];

            // --- STAGE 1 ---
            if (state.currentStage === 1) {
                switch(obj) {
                    case 'bed':
                        if (!state.flags.bedSearched) {
                            addItem('key'); addItem('hammer');
                            state.flags.bedSearched = true;
                            showMessage(messages.bed_find);
                        } else showMessage("もう何もない。");
                        break;
                    case 'brick':
                        if (selected === 'hammer') {
                            addItem('paper'); state.flags.brickBroken = true;
                            showMessage(messages.brick_break);
                        } else showMessage(messages.brick_need_tool);
                        break;
                    case 'wall':
                        if (selected === 'paper') {
                            state.flags.hasCode = true;
                            showMessage(messages.wall_clue);
                        } else showMessage("暗くて読めない。");
                        break;
                    case 'door1':
                        if (selected === 'key' && state.flags.hasCode) {
                            showMessage(messages.door_unlock);
                            setTimeout(() => { removeItem('key'); switchScene(2); }, 1500);
                        } else showMessage(messages.door_locked);
                        break;
                }
            } 
            // --- STAGE 2 ---
            else if (state.currentStage === 2) {
                switch(obj) {
                    case 'toolbox':
                        if (state.flags.toolboxOpened) {
                            showMessage("工具箱は空だ。");
                        } else if (selected === 'key') {
                            showMessage(messages.toolbox_open);
                            addItem('screwdriver'); state.flags.toolboxOpened = true;
                            removeItem('key');
                        } else {
                            if (!state.flags.keyFound2) {
                                showMessage(messages.toolbox_key_hint);
                                addItem('key'); state.flags.keyFound2 = true;
                            } else showMessage(messages.toolbox_locked);
                        }
                        break;
                    case 'panel':
                        if (selected === 'screwdriver') {
                            state.flags.panelFixed = true;
                            state.flags.doorPowerOn = true;
                            showMessage(messages.panel_fixed);
                            document.getElementById('panel-light').classList.replace('bg-red-600', 'bg-green-500');
                        } else showMessage(messages.panel_broken);
                        break;
                    case 'exit2':
                        if (state.flags.doorPowerOn) {
                            showMessage(messages.exit2_success);
                            setTimeout(() => { switchScene(3); }, 1500);
                        } else showMessage(messages.exit2_locked);
                        break;
                }
            }
            // --- STAGE 3 ---
            else if (state.currentStage === 3) {
                switch(obj) {
                    case 'guardbox':
                        if (!state.flags.pliersFound) {
                            addItem('pliers');
                            state.flags.pliersFound = true;
                            showMessage(messages.guardbox_find);
                        } else showMessage("空の警備ボックスだ。");
                        break;
                    case 'wirebox':
                        if (state.flags.lasersOff) {
                            showMessage("配線はすでに切断されている。");
                        } else if (selected === 'pliers') {
                            state.flags.lasersOff = true;
                            showMessage(messages.wirebox_cut);
                            document.querySelectorAll('.laser').forEach(l => l.style.display = 'none');
                            document.getElementById('gate-button').classList.replace('bg-red-900', 'bg-green-600');
                        } else {
                            showMessage(messages.wirebox_danger);
                        }
                        break;
                    case 'gate':
                        if (state.flags.lasersOff) {
                            showMessage(messages.gate_final);
                            setTimeout(() => {
                                document.getElementById('overlay-end').style.display = 'flex';
                            }, 1500);
                        } else {
                            showMessage(messages.gate_locked);
                        }
                        break;
                }
            }
        }

        window.onload = () => {
            showMessage("ここから出なければ... 部屋の中を調べてみよう。");
        };
    </script>
</body>
</html>
🔨 開発中アトリエ

脱出ゲーム

by kizu

脱出するゲーム

🤖 使用したAI
Gemini
👁 4 回閲覧
📅 投稿:2026年3月21日 🔄 更新:2026年4月1日
応援スタンプを押してみよう!