🔬 AI発明ギャラリー o-yuto ポケモンバトルメガ2
🔒 サンドボックス内で実行中 ⛶ 全画面で遊ぶ
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>PokeAPI ポケモンバトル - はじめの仲間たち</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
    <style>
        @import url('https://fonts.googleapis.com/css2?family=DotGothic16&display=swap');

        body {
            font-family: 'Helvetica Neue', Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
            background-color: #1a202c;
            color: #333;
            overflow-x: hidden;
        }

        .pixel-font {
            font-family: 'DotGothic16', sans-serif;
        }

        /* Title Screen Animation */
        .title-float {
            animation: float 3s ease-in-out infinite;
        }
        @keyframes float {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-10px); }
        }

        .battle-screen {
            position: relative;
            height: 350px;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: inset 0 0 50px rgba(0,0,0,0.2);
            transition: all 0.8s ease;
        }

        .bg-grassland { background: linear-gradient(to bottom, #87CEEB 0%, #87CEEB 60%, #90EE90 60%, #90EE90 100%); }
        
        .gmax-bg {
            background: linear-gradient(to bottom, #2d004d 0%, #4b0082 60%, #1a0033 100%) !important;
        }

        .pokemon-img {
            image-rendering: pixelated;
            transition: transform 0.5s ease, opacity 0.5s ease, filter 0.5s;
        }

        .shiny-sparkle {
            animation: sparkle 0.8s ease-in-out infinite;
            filter: drop-shadow(0 0 10px gold);
        }

        @keyframes sparkle {
            0%, 100% { filter: brightness(1) drop-shadow(0 0 5px gold); }
            50% { filter: brightness(1.5) drop-shadow(0 0 15px white); }
        }

        .mega-img {
            transform: scale(1.2) translateY(-10px);
            filter: drop-shadow(0 0 15px rgba(0, 255, 255, 0.6));
        }

        .gmax-img {
            transform: scale(1.6) translateY(-15px);
            filter: drop-shadow(0 0 20px rgba(255, 50, 50, 0.8));
        }

        .evolving {
            animation: evolveEffect 2s infinite;
        }

        @keyframes evolveEffect {
            0% { filter: brightness(1) contrast(1) invert(0); transform: scale(1); }
            50% { filter: brightness(5) contrast(0) invert(1); transform: scale(1.3); }
            100% { filter: brightness(1) contrast(1) invert(0); transform: scale(1); }
        }

        .hp-bar {
            height: 10px;
            transition: width 0.5s ease-in-out;
        }

        .shake { animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both; }
        @keyframes shake {
            10%, 90% { transform: translate3d(-1px, 0, 0); }
            20%, 80% { transform: translate3d(2px, 0, 0); }
            30%, 50%, 70% { transform: translate3d(-4px, 0, 0); }
            40%, 60% { transform: translate3d(4px, 0, 0); }
        }

        .attack-player { animation: attackPlayer 0.5s ease-in-out; }
        @keyframes attackPlayer { 0% { transform: translateX(0); } 50% { transform: translateX(30px) translateY(-20px); } 100% { transform: translateX(0); } }

        .attack-enemy { animation: attackEnemy 0.5s ease-in-out; }
        @keyframes attackEnemy { 0% { transform: translateX(0); } 50% { transform: translateX(-30px) translateY(20px); } 100% { transform: translateX(0); } }

        .message-box {
            background-color: rgba(255, 255, 255, 0.9);
            border: 4px solid #333;
            min-height: 85px;
        }

        .loader {
            border: 4px solid #f3f3f3;
            border-top: 4px solid #3498db;
            border-radius: 50%;
            width: 30px;
            height: 30px;
            animation: spin 2s linear infinite;
        }
        @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }

        .starter-card {
            transition: transform 0.2s;
        }
        .starter-card:hover {
            transform: translateY(-5px);
            border-color: #3b82f6;
        }
    </style>
</head>
<body class="flex flex-col items-center justify-center min-h-screen p-4 bg-gray-900 text-gray-800">

    <div id="game-container" class="max-w-lg w-full bg-white rounded-xl shadow-2xl overflow-hidden border-4 border-gray-800">
        
        <!-- Title Screen -->
        <div id="title-screen" class="p-10 flex flex-col items-center justify-center text-center">
            <div class="mb-8 title-float">
                <h1 class="text-4xl font-black text-blue-600 pixel-font tracking-tighter italic">POCKET<br><span class="text-red-500">BATTLE</span></h1>
                <p class="text-xs font-bold text-gray-400 mt-2">API Edition</p>
            </div>
            <div class="w-24 h-24 mb-10 opacity-20">
                <img src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/items/poke-ball.png" class="w-full h-full object-contain grayscale">
            </div>
            <button onclick="startGame()" class="group relative px-8 py-4 bg-red-600 text-white rounded-full font-bold text-xl shadow-[0_4px_0_rgb(153,27,27)] hover:shadow-none hover:translate-y-1 transition-all pixel-font">
                ぼうけんを はじめる
            </button>
            <p class="mt-8 text-[10px] text-gray-400">PRESS START TO PLAY</p>
        </div>

        <!-- Starter Selection (Initially Hidden) -->
        <div id="starter-selection" class="p-6 hidden">
            <h2 class="text-xl font-bold text-center pixel-font mb-4">冒険に 出かける ポケモンを えらぼう!</h2>
            <div class="grid grid-cols-4 gap-3 max-h-[400px] overflow-y-auto p-2 border-2 border-gray-100 rounded-lg bg-gray-50 shadow-inner" id="starter-list"></div>
            <div id="selection-loader" class="mt-8 flex flex-col items-center">
                <div class="loader mb-2"></div>
                <p class="text-xs text-gray-500">図鑑を 読み込み中...</p>
            </div>
        </div>

        <!-- Battle Screen -->
        <div id="battle-area" class="hidden">
            <div id="battle-bg" class="battle-screen p-4 flex flex-col justify-between bg-grassland">
                <!-- Enemy Area -->
                <div class="flex justify-start items-start">
                    <div id="enemy-stats" class="bg-white/90 p-2 rounded-lg border-2 border-gray-700 w-48 shadow-md">
                        <div class="flex justify-between items-center mb-1">
                            <span id="enemy-name" class="font-bold text-xs truncate mr-1">...</span>
                            <span class="text-[10px] font-bold shrink-0">Lv.50</span>
                        </div>
                        <div class="w-full bg-gray-300 rounded-full border border-gray-400">
                            <div id="enemy-hp-fill" class="hp-bar bg-green-500 rounded-full" style="width: 100%"></div>
                        </div>
                        <div class="text-right text-[10px] mt-1 font-bold" id="enemy-hp-text">0/0</div>
                    </div>
                    <div class="ml-auto relative">
                        <img id="enemy-img" src="" alt="Enemy" class="w-28 h-28 pokemon-img object-contain">
                    </div>
                </div>

                <!-- Player Area -->
                <div class="flex justify-end items-end">
                    <div class="mr-auto">
                        <img id="player-img" src="" alt="Player" class="w-36 h-36 pokemon-img object-contain">
                    </div>
                    <div id="player-stats" class="bg-white/90 p-2 rounded-lg border-2 border-gray-700 w-48 shadow-md">
                        <div class="flex justify-between items-center mb-1">
                            <span id="player-name" class="font-bold text-xs truncate mr-1">...</span>
                            <span class="text-[10px] font-bold shrink-0">Lv.50</span>
                        </div>
                        <div class="w-full bg-gray-300 rounded-full border border-gray-400">
                            <div id="player-hp-fill" class="hp-bar bg-green-500 rounded-full" style="width: 100%"></div>
                        </div>
                        <div class="text-right text-[10px] mt-1 font-bold" id="player-hp-text">0/0</div>
                    </div>
                </div>
            </div>

            <div id="log-container" class="message-box p-3 m-2 rounded-lg border-double border-4 flex flex-col justify-center">
                <p id="message-text" class="text-sm font-bold leading-relaxed pixel-font">...</p>
                <div id="evolution-btn-container" class="hidden mt-2">
                    <button onclick="evolveActivePokemon()" class="w-full bg-yellow-500 text-white font-bold py-1 px-4 rounded shadow-md text-xs pixel-font animate-pulse">進化させる!</button>
                </div>
            </div>

            <div id="controls" class="p-3 bg-gray-200 border-t-4 border-gray-800">
                <div id="action-controls">
                    <div class="grid grid-cols-2 gap-2" id="move-buttons"></div>
                    <div class="mt-2 flex flex-wrap gap-2">
                        <button onclick="healPlayer()" class="flex-1 bg-green-600 text-white font-bold py-2 rounded shadow-md text-xs">きずぐすり</button>
                        <button onclick="toggleBallMenu()" class="flex-1 bg-red-600 text-white font-bold py-2 rounded shadow-md text-xs">捕まえる</button>
                        <button onclick="changeEnemyPokemon()" class="flex-1 bg-indigo-600 text-white font-bold py-2 rounded shadow-md text-xs">別の場所へ</button>
                        <button id="special-transform-btn" onclick="executeSpecialTransformation()" class="hidden flex-1 bg-gradient-to-r from-blue-400 via-purple-500 to-pink-500 text-white font-bold py-2 rounded shadow-md text-xs border-2 border-white/50 animate-bounce">メガシンカ!</button>
                    </div>
                </div>
                
                <div id="ball-selection-menu" class="hidden">
                    <p class="text-[10px] font-bold mb-2 text-center">どのボールを つかいますか?</p>
                    <div class="grid grid-cols-3 gap-2">
                        <button onclick="catchWithBall('common')" class="bg-white border-2 border-red-500 p-2 rounded text-lg flex flex-col items-center">⚾<span class="text-[8px] text-gray-500">モンスター</span></button>
                        <button onclick="catchWithBall('great')" class="bg-white border-2 border-blue-500 p-2 rounded text-lg flex flex-col items-center">🔵<span class="text-[8px] text-gray-500">スーパー</span></button>
                        <button onclick="catchWithBall('ultra')" class="bg-white border-2 border-yellow-500 p-2 rounded text-lg flex flex-col items-center">🟡<span class="text-[8px] text-gray-500">ハイパー</span></button>
                    </div>
                    <button onclick="toggleBallMenu()" class="w-full mt-2 text-[10px] text-gray-500 py-1 underline">キャンセル</button>
                </div>
            </div>
        </div>

        <div id="main-loader" class="p-8 hidden flex flex-col items-center justify-center">
            <div class="loader mb-4"></div>
            <p class="text-gray-600 font-bold">読み込み中...</p>
        </div>
    </div>

    <div id="collection-area" class="max-w-lg w-full mt-4 p-4 bg-white/10 rounded-xl border-2 border-white/20 hidden">
        <div class="flex justify-between items-center mb-2">
            <h3 class="text-white font-bold text-sm"><i class="fas fa-box-open mr-2"></i> てもちのポケモン</h3>
            <span class="text-yellow-400 text-[10px] font-bold">色違い確率: 20%</span>
        </div>
        <div id="collection-list" class="flex flex-wrap gap-2"></div>
    </div>

    <script>
        const API_URL = "https://pokeapi.co/api/v2/pokemon/";
        const SHINY_CHANCE = 0.2;

        let activePartnerId = null; 
        let player = null;
        let enemy = null;
        let isProcessing = false;
        let capturedPokemons = []; 
        let isTransformed = false;
        
        const MEGA_MAP = { 
            3: 10033, 6: 10034, 9: 10036, 65: 10037, 94: 10038, 257: 10050, 384: 10084, 445: 10058, 448: 10059 
        };

        const GMAX_LIST = { 
            6: "charizard-gmax", 25: "pikachu-gmax", 133: "eevee-gmax", 143: "snorlax-gmax", 94: "gengar-gmax", 131: "lapras-gmax", 68: "machamp-gmax" 
        };
        
        const ballData = { common: { name: "モンスターボール", rate: 1.0 }, great: { name: "スーパーボール", rate: 1.5 }, ultra: { name: "ハイパーボール", rate: 2.5 } };

        function startGame() {
            document.getElementById('title-screen').classList.add('hidden');
            document.getElementById('starter-selection').classList.remove('hidden');
            initStarterSelection();
        }

        function getJapaneseName(names) {
            const ja = names.find(n => n.language.name === 'ja-Hrkt' || n.language.name === 'ja');
            return ja ? ja.name : names[0].name;
        }

        async function fetchPokemon(idOrName, forcedShiny = null) {
            const isShiny = forcedShiny !== null ? forcedShiny : Math.random() < SHINY_CHANCE;
            const pokeRes = await fetch(`${API_URL}${idOrName}`);
            const data = await pokeRes.json();
            const speciesRes = await fetch(data.species.url);
            const speciesData = await speciesRes.json();
            
            let japaneseName = getJapaneseName(speciesData.names);
            const isGmax = data.name.includes('-gmax');
            const isMega = data.id >= 10000;

            if (isGmax) {
                japaneseName = `キョダイ${japaneseName}`;
            } else if (isMega) {
                if (data.id === 10035) japaneseName = "メガリザードンY";
                else if (data.id === 10034) japaneseName = "メガリザードンX";
                else japaneseName = `メガ${japaneseName}`;
            }

            let moves = [];
            if (isGmax || isMega) {
                const prefix = isGmax ? "キョダイ" : "メガ";
                moves = [
                    { name: `${prefix}${japaneseName.replace(prefix, '')}わざ`, power: 150 },
                    { name: isMega ? "はかいこうせん" : "ダイマックスほう", power: 120 },
                    { name: "サイコキネシス", power: 90 },
                    { name: "しんそく", power: 80 }
                ];
            } else {
                moves = await Promise.all(data.moves.slice(0, 4).map(async (m) => {
                    const moveRes = await fetch(m.move.url);
                    const moveData = await moveRes.json();
                    return { name: getJapaneseName(moveData.names), power: moveData.power || 50 };
                }));
            }

            const sprites = data.sprites.versions['generation-v']?.['black-white']?.animated || data.sprites;
            
            return {
                baseId: data.id >= 10000 ? speciesData.id : data.id,
                id: data.id,
                name: japaneseName,
                hp: data.stats[0].base_stat * (isGmax || isMega ? 3 : 2),
                maxHp: data.stats[0].base_stat * (isGmax || isMega ? 3 : 2),
                attack: data.stats[1].base_stat * (isGmax || isMega ? 1.6 : 1),
                defense: data.stats[2].base_stat * (isGmax || isMega ? 1.4 : 1),
                sprite: isShiny ? (sprites.front_shiny || data.sprites.front_shiny) : (sprites.front_default || data.sprites.front_default),
                backSprite: isShiny ? (sprites.back_shiny || data.sprites.back_shiny) : (sprites.back_default || data.sprites.back_default),
                staticSprite: isShiny ? data.sprites.front_shiny : data.sprites.front_default,
                moves: moves,
                speciesUrl: data.species.url,
                wins: 0,
                isShiny: isShiny,
                isGmax: isGmax,
                isMega: isMega
            };
        }

        async function initStarterSelection() {
            const starters = [1, 4, 7, 152, 155, 158, 252, 255, 258, 387, 390, 393, 25, 133, 447, 92];
            const starterList = document.getElementById('starter-list');
            starterList.innerHTML = '';
            
            for (const id of starters) {
                try {
                    const pokemon = await fetchPokemon(id);
                    const card = document.createElement('div');
                    card.className = `starter-card p-2 rounded-lg text-center border-2 cursor-pointer flex flex-col items-center bg-white border-gray-200`;
                    card.onclick = () => {
                        addCollection(pokemon);
                        switchActivePokemon(pokemon.id);
                        document.getElementById('starter-selection').classList.add('hidden');
                        document.getElementById('collection-area').classList.remove('hidden');
                        startNewBattle();
                    };
                    card.innerHTML = `
                        <img src="${pokemon.staticSprite}" class="w-12 h-12">
                        <p class="text-[8px] font-bold mt-1">${pokemon.name}</p>
                    `;
                    starterList.appendChild(card);
                } catch(e) { console.error(e); }
            }
            document.getElementById('selection-loader').classList.add('hidden');
        }

        async function changeEnemyPokemon() {
            if (isProcessing) return;
            updateMessage("別の場所へ ポケモンを さがしにいく...");
            await new Promise(r => setTimeout(r, 800));
            startNewBattle();
        }

        function switchActivePokemon(id) {
            const target = capturedPokemons.find(p => p.id === id);
            if (!target) return;
            activePartnerId = id;
            player = JSON.parse(JSON.stringify(target)); 
            isTransformed = false;
            updateUI();
            renderMoves();
            renderCollection();
        }

        async function startNewBattle() {
            isProcessing = true;
            document.getElementById('main-loader').classList.remove('hidden');
            document.getElementById('battle-area').classList.add('hidden');
            document.getElementById('battle-bg').classList.remove('gmax-bg');
            
            try {
                const randomId = Math.floor(Math.random() * 800) + 1;
                enemy = await fetchPokemon(randomId);
                
                updateUI();
                renderMoves();
                document.getElementById('main-loader').classList.add('hidden');
                document.getElementById('battle-area').classList.remove('hidden');
                
                updateMessage(enemy.isShiny ? `★野生の 色違い ${enemy.name} が とびだしてきた!★` : `あ! 野生の ${enemy.name} が とびだしてきた!`);
                isProcessing = false;
            } catch (e) { startNewBattle(); }
        }

        function updateUI() {
            if (!player || !enemy) return;
            const pImgEl = document.getElementById('player-img');
            document.getElementById('player-name').innerText = (player.isShiny ? '★' : '') + player.name;
            pImgEl.src = player.backSprite || player.sprite;
            
            pImgEl.classList.remove('gmax-img', 'mega-img');
            const bg = document.getElementById('battle-bg');
            bg.classList.remove('gmax-bg');

            if (player.isGmax) { pImgEl.classList.add('gmax-img'); bg.classList.add('gmax-bg'); }
            else if (player.isMega) { pImgEl.classList.add('mega-img'); bg.classList.add('gmax-bg'); }
            
            updateHPBar('player', player.hp, player.maxHp);
            document.getElementById('enemy-name').innerText = (enemy.isShiny ? '★' : '') + enemy.name;
            document.getElementById('enemy-img').src = enemy.sprite;
            updateHPBar('enemy', enemy.hp, enemy.maxHp);

            const specialBtn = document.getElementById('special-transform-btn');
            const baseId = player.baseId || player.id;
            const canMega = MEGA_MAP[baseId] && !isTransformed;
            const canGmax = GMAX_LIST[baseId] && !isTransformed;
            
            if (canMega || canGmax) {
                specialBtn.classList.remove('hidden');
                specialBtn.innerText = canMega ? "メガシンカ!" : "キョダイマックス!";
            } else {
                specialBtn.classList.add('hidden');
            }
        }

        function updateHPBar(who, current, max) {
            const percent = Math.max(0, (current / max) * 100);
            const fill = document.getElementById(`${who}-hp-fill`);
            fill.style.width = `${percent}%`;
            fill.className = `hp-bar ${percent < 20 ? 'bg-red-500' : percent < 50 ? 'bg-yellow-500' : 'bg-green-500'} rounded-full`;
            document.getElementById(`${who}-hp-text`).innerText = `${Math.ceil(current)} / ${max}`;
        }

        function renderMoves() {
            const container = document.getElementById('move-buttons');
            container.innerHTML = '';
            player.moves.forEach(move => {
                const btn = document.createElement('button');
                btn.className = `border-2 font-bold py-2 rounded text-[11px] shadow-sm transition-all active:scale-95 ${move.power >= 100 ? 'bg-red-50 border-red-500 text-red-700' : 'bg-white border-gray-400'}`;
                btn.innerText = move.name;
                btn.onclick = () => handleAttack(move);
                container.appendChild(btn);
            });
        }

        function updateMessage(text) { document.getElementById('message-text').innerText = text; }

        async function handleAttack(move) {
            if (isProcessing) return;
            isProcessing = true;
            await performMove(player, enemy, move, 'player');
            if (enemy.hp <= 0) {
                updateMessage(`${enemy.name} を たおした!`);
                recordWin(); 
                showBattleEndOptions();
                return;
            }
            await enemyTurn();
        }

        async function enemyTurn() {
            await new Promise(r => setTimeout(r, 1000));
            const move = enemy.moves[Math.floor(Math.random() * enemy.moves.length)];
            await performMove(enemy, player, move, 'enemy');
            if (player.hp <= 0) {
                updateMessage(`${player.name} は たおれてしまった...`);
                showBattleEndOptions();
                return;
            }
            isProcessing = false;
        }

        async function performMove(attacker, defender, move, role) {
            updateMessage(`${attacker.name} の ${move.name}!`);
            document.getElementById(`${role}-img`).classList.add(role === 'player' ? 'attack-player' : 'attack-enemy');
            await new Promise(r => setTimeout(r, 500));
            document.getElementById(`${role}-img`).classList.remove(role === 'player' ? 'attack-player' : 'attack-enemy');
            
            if (move.power > 0) {
                let damage = (((2 * 50 / 5 + 2) * move.power * (attacker.attack / defender.defense)) / 50) + 2;
                defender.hp = Math.max(0, defender.hp - damage);
                document.getElementById(role === 'player' ? 'enemy-img' : 'player-img').classList.add('shake');
                updateHPBar(role === 'player' ? 'enemy' : 'player', defender.hp, defender.maxHp);
                await new Promise(r => setTimeout(r, 500));
                document.getElementById(role === 'player' ? 'enemy-img' : 'player-img').classList.remove('shake');
            } else {
                updateMessage(`${attacker.name} は まもりを かためた!`);
                await new Promise(r => setTimeout(r, 800));
            }
        }

        function showBattleEndOptions() {
            const container = document.getElementById('move-buttons');
            container.innerHTML = `
                <button onclick="startNewBattle()" class="col-span-2 bg-blue-600 text-white font-bold py-3 rounded text-sm pixel-font shadow-lg hover:bg-blue-700">次のポケモンを さがす</button>
            `;
            isProcessing = false;
        }

        function toggleBallMenu() {
            document.getElementById('action-controls').classList.toggle('hidden');
            document.getElementById('ball-selection-menu').classList.toggle('hidden');
        }

        async function catchWithBall(ballType) {
            toggleBallMenu();
            isProcessing = true;
            updateMessage(`${ballData[ballType].name} を なげた!`);
            await new Promise(r => setTimeout(r, 1000));
            const catchRate = 0.4 * ballData[ballType].rate * (1 + (1 - (enemy.hp / enemy.maxHp)));
            if (Math.random() < catchRate) {
                updateMessage(`${enemy.name} を つかまえた!`);
                addCollection(enemy); 
                showBattleEndOptions();
            } else {
                updateMessage("だめだ! ボールから もれだしてしまった!"); 
                await enemyTurn();
            }
        }

        async function executeSpecialTransformation() {
            if (isProcessing) return;
            isProcessing = true;
            isTransformed = true;
            const baseId = player.baseId || player.id;
            const targetId = MEGA_MAP[baseId] || GMAX_LIST[baseId];
            updateMessage(`${player.name} は キーストーンに 反応している!`);
            document.getElementById('player-img').classList.add('evolving');
            await new Promise(r => setTimeout(r, 2000));
            const newForm = await fetchPokemon(targetId, player.isShiny);
            const hpRatio = player.hp / player.maxHp;
            const wins = player.wins;
            player = newForm;
            player.hp = player.maxHp * hpRatio;
            player.wins = wins;
            document.getElementById('player-img').classList.remove('evolving');
            updateUI(); 
            renderMoves();
            updateMessage(`${player.name} へ 変身した!`);
            isProcessing = false;
        }

        function healPlayer() {
            if (isProcessing || player.hp >= player.maxHp) return;
            isProcessing = true;
            player.hp = Math.min(player.maxHp, player.hp + 60);
            updateHPBar('player', player.hp, player.maxHp);
            updateMessage(`${player.name} の きずが いえた!`);
            setTimeout(enemyTurn, 800);
        }

        function recordWin() {
            const p = capturedPokemons.find(p => (p.baseId || p.id) === (player.baseId || player.id));
            if (p) { p.wins++; checkEvolution(p); }
        }

        function checkEvolution(p) { if (p.wins >= 2) document.getElementById('evolution-btn-container').classList.remove('hidden'); }

        async function evolveActivePokemon() {
            if (isProcessing) return;
            isProcessing = true;
            document.getElementById('evolution-btn-container').classList.add('hidden');
            updateMessage(`${player.name} の ようすが おかしい...?`);
            document.getElementById('player-img').classList.add('evolving');
            await new Promise(r => setTimeout(r, 2000));
            try {
                const res = await fetch(player.speciesUrl);
                const speciesData = await res.json();
                const evoRes = await fetch(speciesData.evolution_chain.url);
                const evoData = await evoRes.json();
                let current = evoData.chain;
                while (current && current.species.name !== speciesData.name) current = current.evolves_to[0];
                if (current && current.evolves_to.length > 0) {
                    const evolved = await fetchPokemon(current.evolves_to[0].species.name, player.isShiny);
                    const idx = capturedPokemons.findIndex(x => (x.baseId || x.id) === (player.baseId || player.id));
                    capturedPokemons[idx] = evolved;
                    switchActivePokemon(evolved.id);
                    updateMessage(`${evolved.name} に しんかした!`);
                }
            } catch (e) { console.error(e); }
            document.getElementById('player-img').classList.remove('evolving');
            isProcessing = false;
        }

        function addCollection(p) { 
            const exists = capturedPokemons.find(x => (x.baseId || x.id) === (p.baseId || p.id));
            if (!exists) capturedPokemons.push(p); 
            renderCollection(); 
        }
        
        function renderCollection() {
            const list = document.getElementById('collection-list');
            list.innerHTML = '';
            capturedPokemons.forEach(p => {
                const item = document.createElement('div');
                // playerがまだ存在しない場合を考慮して?.を使用(初期選択時など)
                const isActive = player && (p.baseId || p.id) === (player.baseId || player.id);
                item.className = `w-10 h-10 bg-white rounded border-2 cursor-pointer flex items-center justify-center relative ${isActive ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-300'}`;
                item.innerHTML = `<img src="${p.staticSprite}" class="w-full h-full object-contain ${p.isShiny ? 'shiny-sparkle' : ''}">`;
                item.onclick = () => !isProcessing && switchActivePokemon(p.id);
                list.appendChild(item);
            });
        }
    </script>
</body>
</html>

ポケモンバトルメガ2

by o-yuto

ポケモンバトルゲーム

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