🔬 AI発明ギャラリー ryusei ポケモンクイズ
🔒 サンドボックス内で実行中 ⛶ 全画面で遊ぶ
HTML / CSS / JS
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>コライドン (Koraidon) 2Dデジタルフィギュア&クイズ</title>
    <!-- Tailwind CSS for UI styling -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- FontAwesome for Icons -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background-color: #0b0f19;
            font-family: 'Helvetica Neue', Arial, 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif;
            touch-action: none; /* スマホでの誤スクロール・ピンチズームを防止 */
        }
        /* スライダーなどのカスタマイズ */
        input[type="range"] {
            -webkit-appearance: none;
            appearance: none;
            background: #1e293b;
            height: 12px; /* タッチしやすい太さに */
            border-radius: 9999px;
            border: 1px solid #334155;
        }
        input[type="range"]::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 26px; /* タッチターゲットのサイズアップ */
            height: 26px;
            border-radius: 50%;
            background: #ef4444;
            cursor: pointer;
            border: 3px solid #ffffff;
            box-shadow: 0 0 10px rgba(239, 68, 68, 0.5);
            transition: transform 0.1s;
        }
        .no-scrollbar::-webkit-scrollbar {
            display: none;
        }
        .no-scrollbar {
            -ms-overflow-style: none;
            scrollbar-width: none;
        }
        /* シルエットを確実に表現するためのカスタムCSS */
        .silhouette {
            filter: brightness(0) contrast(100%) !important;
            -webkit-filter: brightness(0) contrast(100%) !important;
        }
        /* キャンバスをくっきり表示 */
        canvas {
            image-rendering: -moz-crisp-edges;
            image-rendering: -webkit-crisp-edges;
            image-rendering: pixelated;
            image-rendering: crisp-edges;
            display: block;
            touch-action: none;
        }
    </style>
</head>
<body class="text-slate-100 select-none no-scrollbar">

    <!-- 2Dグラフィック描画用 Canvas -->
    <canvas id="stage-canvas" class="absolute inset-0 w-full h-full z-0"></canvas>

    <!-- UIオーバーレイ -->
    <div id="ui-overlay" class="absolute inset-0 pointer-events-none z-10 flex flex-col justify-between p-3 md:p-6 opacity-0 transition-opacity duration-700">
        
        <!-- ヘッダーエリア -->
        <header class="flex flex-col sm:flex-row justify-between items-start pointer-events-auto w-full gap-2">
            <div class="bg-slate-950/90 border-2 border-red-500 rounded-3xl p-3 md:p-4 shadow-[0_0_20px_rgba(239,68,68,0.2)] max-w-xs md:max-w-sm">
                <div class="flex items-center gap-2 mb-1">
                    <span class="bg-gradient-to-r from-red-600 to-rose-500 text-white text-[9px] md:text-xs px-2 py-0.5 rounded-full font-bold uppercase tracking-widest animate-pulse">2D デジタルフィギュア</span>
                    <span class="text-yellow-400 text-[10px] md:text-xs font-bold">★パルデアちほう</span>
                </div>
                <h1 class="text-xl md:text-3xl font-black tracking-wider text-transparent bg-clip-text bg-gradient-to-r from-red-500 via-orange-500 to-yellow-400">
                    コライドン <span class="text-[10px] text-slate-300 font-normal">Koraidon</span>
                </h1>
                <p class="text-[10px] md:text-[11px] text-slate-300 mt-1 leading-relaxed">
                    スワイプ(なぞる)すると むきを かえられるよ!<br>
                    コライドンを タッチすると ほえるよ!
                </p>
            </div>

            <!-- 右上:ミニゲームスコアとあそびかた -->
            <div class="flex flex-row sm:flex-col items-center sm:items-end justify-between w-full sm:w-auto gap-2">
                <div class="bg-slate-950/95 border-2 border-yellow-500 rounded-2xl px-3 py-1.5 shadow-lg flex items-center gap-2">
                    <span class="text-yellow-400 font-extrabold text-xs md:text-sm"><i class="fa-solid fa-star animate-spin mr-1"></i>スコア:</span>
                    <span id="score-val" class="text-xl font-black text-white font-mono">0</span>
                </div>
                <div class="flex gap-1.5">
                    <button id="btn-quiz-open" class="bg-gradient-to-r from-amber-500 to-yellow-500 hover:from-amber-400 hover:to-yellow-400 text-slate-950 font-black px-3.5 py-2 rounded-xl shadow-[0_0_15px_rgba(245,158,11,0.3)] transition transform active:scale-95 text-xs flex items-center gap-1">
                        <i class="fa-solid fa-gamepad text-base"></i> クイズであそぶ!
                    </button>
                    <button id="btn-sound-toggle" class="bg-slate-950/90 hover:bg-slate-900 border-2 border-slate-700 text-white p-2.5 rounded-xl transition shadow-lg flex items-center justify-center" title="おんせいオン/オフ">
                        <i id="sound-icon" class="fa-solid fa-volume-high text-base text-emerald-400"></i>
                    </button>
                </div>
            </div>
        </header>

        <!-- PokeAPI クイズウィンドウ (ポップアップ) -->
        <div id="quiz-window" class="hidden fixed inset-0 bg-black/85 backdrop-blur-sm z-50 flex items-center justify-center p-3 md:p-4 pointer-events-auto">
            <div class="bg-slate-950 border-4 border-yellow-400 rounded-3xl p-4 md:p-5 max-w-md w-full shadow-[0_0_50px_rgba(234,179,8,0.3)] relative">
                
                <!-- 閉じるボタン -->
                <button id="btn-quiz-close" class="absolute -top-3 -right-3 bg-red-600 hover:bg-red-500 text-white w-10 h-10 rounded-full flex items-center justify-center font-bold border-2 border-white text-lg shadow-lg">
                    <i class="fa-solid fa-xmark"></i>
                </button>

                <!-- クイズ本体 -->
                <div id="quiz-loading" class="text-center py-10">
                    <i class="fa-solid fa-circle-notch animate-spin text-4xl text-yellow-400 mb-3"></i>
                    <p class="text-sm font-bold text-yellow-200">ポケモンの データを よみこんでいるよ...</p>
                </div>

                <div id="quiz-error" class="hidden text-center py-10 text-red-400">
                    <i class="fa-solid fa-triangle-exclamation text-4xl mb-3 animate-bounce"></i>
                    <p class="text-sm font-bold">つうしんが しっぱいしたよ。もういちど試してね。</p>
                    <button id="btn-quiz-retry" class="mt-4 bg-yellow-400 hover:bg-yellow-300 text-slate-950 px-5 py-2 rounded-lg text-xs font-black shadow-md">もういちどトライ</button>
                </div>

                <div id="quiz-content" class="hidden space-y-3.5">
                    <div class="text-center">
                        <span class="bg-yellow-400 text-slate-950 text-[10px] md:text-xs font-black px-3.5 py-1 rounded-full uppercase tracking-wider">このポケモン だーれだ?</span>
                        <h3 class="text-sm md:text-base font-black text-slate-200 mt-1.5">シルエットの ポケモンを あててね!</h3>
                    </div>

                    <!-- ポケモンの影絵/画像表示エリア -->
                    <div class="relative bg-slate-900 rounded-2xl p-3 flex items-center justify-center h-40 md:h-44 border-2 border-slate-800 overflow-hidden shadow-inner">
                        <div class="absolute text-slate-800/10 text-8xl font-black pointer-events-none">?</div>
                        <!-- ポケモン画像 -->
                        <img id="quiz-pokemon-img" class="h-32 w-32 md:h-36 md:w-36 object-contain transition-all duration-500 silhouette" src="" alt="Pokemon Silhouette">
                    </div>

                    <!-- ヒント情報 -->
                    <div class="bg-slate-900/80 p-2.5 rounded-xl text-[11px] space-y-1 text-slate-300 border border-slate-800">
                        <div class="flex justify-between"><span>タイプ:</span> <span id="quiz-pokemon-type" class="font-bold text-yellow-300">-</span></div>
                        <div class="flex justify-between"><span>おもさ:</span> <span id="quiz-pokemon-weight" class="font-bold text-slate-100">-</span></div>
                    </div>

                    <!-- 選択肢ボタン (4択) -->
                    <div class="grid grid-cols-2 gap-2" id="quiz-options">
                        <!-- JSで動的にボタンを生成します -->
                    </div>

                    <!-- 結果表示エリア -->
                    <div id="quiz-feedback" class="hidden text-center p-2.5 rounded-xl font-bold text-xs md:text-sm border-2 transition duration-300">
                        <p id="feedback-text"></p>
                        <button id="btn-next-quiz" class="mt-2 bg-yellow-400 hover:bg-yellow-300 text-slate-950 px-6 py-2 rounded-lg text-xs font-black shadow-md transition">
                            つぎのクイズへ! <i class="fa-solid fa-arrow-right"></i>
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- 下部のコントロールパネル -->
        <div class="flex flex-col md:flex-row gap-3 justify-between items-end w-full pointer-events-auto">
            
            <!-- 左下:背景(はいけい)えらび -->
            <div class="bg-slate-950/95 border-2 border-red-500/30 rounded-2xl p-3 shadow-xl max-w-xs hidden md:block">
                <div class="text-xs font-bold text-rose-400 uppercase tracking-wider mb-2 flex items-center gap-1.5">
                    <i class="fa-solid fa-mountain-sun"></i>
                    <span>ステージ(背景)を かえよう!</span>
                </div>
                <div class="grid grid-cols-3 gap-1.5">
                    <button class="bg-sky-950/80 hover:bg-sky-900 border border-sky-500 text-sky-300 py-1 px-2 rounded-lg font-bold text-[10px] btn-bg-stage" data-bg="day">はれ</button>
                    <button class="bg-amber-950/80 hover:bg-amber-900 border border-amber-500 text-amber-300 py-1 px-2 rounded-lg font-bold text-[10px] btn-bg-stage" data-bg="sunset">ゆうがた</button>
                    <button class="bg-indigo-950/80 hover:bg-indigo-900 border border-indigo-500 text-indigo-300 py-1 px-2 rounded-lg font-bold text-[10px] btn-bg-stage" data-bg="night">よぞら</button>
                </div>
            </div>

            <!-- 右下:コライドン 2Dコントロールボード -->
            <div class="bg-slate-950/95 border-2 border-red-500/50 rounded-3xl p-3 md:p-4 shadow-2xl w-full md:max-w-md">
                <div class="flex items-center justify-between mb-2 border-b border-slate-800 pb-1.5">
                    <div class="flex items-center gap-1.5">
                        <i class="fa-solid fa-dragon text-rose-500 text-base animate-bounce"></i>
                        <span class="font-black text-xs md:text-sm text-slate-100">コライドンを うごかそう!</span>
                    </div>
                    <!-- スマホ向けに背景切り替えをミニボタン化して格納 -->
                    <div class="flex md:hidden gap-1">
                        <button class="bg-sky-950 border border-sky-500 text-sky-300 px-1.5 py-0.5 rounded text-[9px] font-bold btn-bg-stage" data-bg="day">はれ</button>
                        <button class="bg-amber-950 border border-amber-500 text-amber-300 px-1.5 py-0.5 rounded text-[9px] font-bold btn-bg-stage" data-bg="sunset">夕方</button>
                        <button class="bg-indigo-950 border border-indigo-500 text-indigo-300 px-1.5 py-0.5 rounded text-[9px] font-bold btn-bg-stage" data-bg="night">夜空</button>
                    </div>
                </div>

                <!-- スライダーコントロール -->
                <div class="grid grid-cols-1 sm:grid-cols-2 gap-2 text-[11px] mb-2.5">
                    <!-- アニメーション速度 -->
                    <div>
                        <div class="flex justify-between mb-0.5 text-slate-300 font-bold">
                            <span>うごく はやさ</span>
                            <span class="text-rose-400 font-black" id="val-speed">1.0x</span>
                        </div>
                        <input type="range" id="slider-speed" min="0" max="2" step="0.1" value="1" class="w-full">
                    </div>

                    <!-- エフェクトの強さ -->
                    <div class="hidden sm:block">
                        <div class="flex justify-between mb-0.5 text-slate-300 font-bold">
                            <span>エフェクトの強さ</span>
                            <span class="text-rose-400 font-black" id="val-effects">1.0x</span>
                        </div>
                        <input type="range" id="slider-effects" min="0.5" max="2.0" step="0.1" value="1.0" class="w-full">
                    </div>
                </div>

                <!-- モーション・ポーズボタン -->
                <div class="space-y-1">
                    <div class="grid grid-cols-3 gap-1.5">
                        <button id="pose-stand" class="bg-rose-600 hover:bg-rose-500 text-white py-2 px-1 rounded-xl font-bold transition duration-200 shadow-md text-xs">
                            <i class="fa-solid fa-paw mr-1"></i>たたずむ
                        </button>
                        <button id="pose-flight" class="bg-slate-900 hover:bg-slate-800 text-slate-300 py-2 px-1 rounded-xl font-bold transition duration-200 text-xs">
                            <i class="fa-solid fa-wind mr-1"></i>とぶ!
                        </button>
                        <button id="pose-glow" class="bg-slate-900 hover:bg-slate-800 text-slate-300 py-2 px-1 rounded-xl font-bold transition duration-200 text-xs">
                            <i class="fa-solid fa-volume-high mr-1"></i>ほえる!
                        </button>
                    </div>
                </div>
            </div>

        </div>
    </div>

    <!-- MAIN INTERACTIVE RENDERING LOGIC -->
    <script>
        const canvas = document.getElementById('stage-canvas');
        const ctx = canvas.getContext('2d');

        let speedMultiplier = 1.0;
        let effectsIntensity = 1.0;
        let currentPose = 'stand'; // 'stand', 'flight', 'glow'
        let currentBgStage = 'day'; // 'day', 'sunset', 'night'
        let speakEnabled = true;

        // モバイル向け:ドラッグ・タッチ操作による左右回転パラメータ
        let koraidonRotateY = 0; // スワイプした時の追加回転角
        let isDragging = false;
        let startX = 0;

        // 音声の最初のインタラクション解放フラグ
        let audioUnlocked = false;

        // タイマー管理
        let lastTime = 0;
        let totalTime = 0;

        // 咆哮モード用の音波リング管理配列
        let roarRings = [];

        // 星屑(粒子)エフェクトの配列
        const particles = [];
        for (let i = 0; i < 35; i++) {
            particles.push({
                x: Math.random(),
                y: Math.random(),
                size: 1 + Math.random() * 3,
                speedX: 0.1 + Math.random() * 0.3,
                speedY: 0.05 + Math.random() * 0.15,
                opacity: 0.2 + Math.random() * 0.6
            });
        }

        // コライドン・カラーパレット
        const COLOR = {
            scarlet: '#d61c22',       // 緋色・メインの赤
            scarletLight: '#f25a5a',  // あかるいお腹の赤
            cream: '#f5f0e1',         // 爪やアンテナのクリーム白
            white: '#ffffff',         // 純白
            blue: '#004e98',          // トサカ・マントのロイヤルブルー
            darkBlue: '#0a1128',      // タイヤの中の暗色
            magenta: '#d81159',       // リボン根元の鮮烈なピンク
            grey: '#1c1c1e',          // タイヤのゴム色
            gold: '#fca311',          // 金色の目・模様アクセント
            orange: '#f77f00',        // 瞳孔周辺のオレンジ
            pupil: '#0e0e11'          // 漆黒
        };

        // キャンバスサイズ自動調整(Retina対応)
        function resizeCanvas() {
            const dpr = window.devicePixelRatio || 1;
            canvas.width = window.innerWidth * dpr;
            canvas.height = window.innerHeight * dpr;
            
            // CSSサイズをデバイス幅に固定
            canvas.style.width = window.innerWidth + 'px';
            canvas.style.height = window.innerHeight + 'px';
            
            // コンテキストの描画比率をデバイス比に合わせる
            ctx.scale(dpr, dpr);
        }
        window.addEventListener('resize', resizeCanvas);
        resizeCanvas();

        // いなずまダイヤマークを描く便利なヘルパー関数
        function drawLightningMark(ctx, x, y, size, angle) {
            ctx.save();
            ctx.translate(x, y);
            ctx.rotate(angle);
            ctx.fillStyle = COLOR.white;
            ctx.beginPath();
            ctx.moveTo(0, -size);
            ctx.lineTo(size * 0.4, -size * 0.2);
            ctx.lineTo(size * 0.1, 0);
            ctx.lineTo(size * 0.5, size * 0.6);
            ctx.lineTo(-size * 0.1, size);
            ctx.lineTo(-size * 0.2, size * 0.2);
            ctx.lineTo(0, 0);
            ctx.closePath();
            ctx.fill();
            ctx.restore();
        }

        // つやつやしたグラデーション付きの丸みのあるボディを描く(2Dベクター)
        function drawKoraidon(ctx, cx, cy, scale, t) {
            ctx.save();
            ctx.translate(cx, cy);
            ctx.scale(scale, scale);

            // ドラッグ(スワイプ)による回転角を適用
            ctx.rotate(koraidonRotateY);

            // ポーズごとのボディの配置調整
            let bodyX = 0;
            let bodyY = 0;
            let bodyRotation = 0;
            let headX = 60;
            let headY = -120;
            let headRotation = 0;
            let tailRotation = 0;
            
            // 飛行状態・咆哮状態による変化
            if (currentPose === 'stand') {
                bodyY = Math.sin(t * 3.5) * 5;
                headY += Math.cos(t * 3) * 3;
                tailRotation = Math.sin(t * 2) * 0.15;
            } else if (currentPose === 'flight') {
                bodyY = Math.sin(t * 6.0) * 12;
                bodyRotation = -0.15 + Math.sin(t * 5) * 0.05;
                headX = 80;
                headY = -100;
                headRotation = 0.1 + Math.cos(t * 6.0) * 0.05;
                tailRotation = Math.sin(t * 8.0) * 0.4;
            } else if (currentPose === 'glow') {
                bodyX = (Math.random() - 0.5) * 2;
                bodyY = (Math.random() - 0.5) * 2;
                headY = -140;
                headRotation = -0.4 + Math.sin(t * 12.0) * 0.04; // 上を向く!
                tailRotation = Math.sin(t * 10) * 0.25;
            }

            ctx.translate(bodyX, bodyY);
            ctx.rotate(bodyRotation);

            // 1. 【しっぽ (Tail)】
            ctx.save();
            ctx.translate(-120, -10);
            ctx.rotate(tailRotation);
            
            // 節々のうねりを描く
            for (let i = 0; i < 5; i++) {
                ctx.translate(-25, 10);
                ctx.rotate(Math.sin(t * 3 + i) * 0.1);
                
                // 節本体
                let segGrad = ctx.createLinearGradient(0, -20, 0, 20);
                segGrad.addColorStop(0, COLOR.scarletLight);
                segGrad.addColorStop(1, COLOR.scarlet);
                ctx.fillStyle = segGrad;
                ctx.beginPath();
                ctx.arc(0, 0, 28 - i * 4, 0, Math.PI * 2);
                ctx.fill();

                // 棘(トゲ)
                ctx.fillStyle = (i % 2 === 0) ? COLOR.blue : COLOR.cream;
                ctx.beginPath();
                ctx.moveTo(0, -25 + i * 3);
                ctx.lineTo(-12, 0);
                ctx.lineTo(12, 0);
                ctx.closePath();
                ctx.fill();
            }
            ctx.restore();

            // 2. 【後肢 (Back Leg)】
            ctx.save();
            ctx.translate(-70, 30);
            if (currentPose === 'flight') {
                ctx.rotate(Math.PI / 3); // 飛行中は折りたたむ
            } else {
                ctx.rotate(Math.sin(t * 3) * 0.05);
            }
            // 腿
            let thighGrad = ctx.createRadialGradient(-10, -10, 5, 0, 0, 45);
            thighGrad.addColorStop(0, COLOR.scarletLight);
            thighGrad.addColorStop(1, COLOR.scarlet);
            ctx.fillStyle = thighGrad;
            ctx.beginPath();
            ctx.ellipse(0, 0, 35, 50, Math.PI/6, 0, Math.PI * 2);
            ctx.fill();
            // 太ももの白い稲妻マーク
            drawLightningMark(ctx, 15, -10, 18, -Math.PI / 10);

            // 下腿・足
            ctx.fillStyle = COLOR.scarlet;
            ctx.beginPath();
            ctx.ellipse(10, 45, 18, 30, -Math.PI/12, 0, Math.PI * 2);
            ctx.fill();
            
            // 白い3本爪
            ctx.fillStyle = COLOR.cream;
            for (let i = 0; i < 3; i++) {
                ctx.beginPath();
                ctx.arc(20 + i * 8, 70, 7, 0, Math.PI, true);
                ctx.closePath();
                ctx.fill();
            }
            ctx.restore();

            // 3. 【胴体 (Torso)】
            // 陰影を表現する豪華なグラデーション
            let bodyGrad = ctx.createLinearGradient(-120, -50, 100, 50);
            bodyGrad.addColorStop(0, COLOR.scarlet);
            bodyGrad.addColorStop(0.5, COLOR.scarletLight);
            bodyGrad.addColorStop(1, COLOR.scarlet);
            
            ctx.fillStyle = bodyGrad;
            ctx.beginPath();
            ctx.ellipse(0, -10, 110, 60, Math.PI / 16, 0, Math.PI * 2);
            ctx.fill();

            // お腹の白い毛フサフサ
            ctx.fillStyle = COLOR.cream;
            ctx.beginPath();
            ctx.ellipse(30, 20, 50, 35, -Math.PI / 12, 0, Math.PI * 2);
            ctx.fill();

            // 4. 【お尻タイヤ (Rear Wheel - 収縮状態)】
            ctx.save();
            ctx.translate(-100, 20);
            let wheelRot = (currentPose === 'flight') ? t * 8.0 : t * 0.3;
            ctx.rotate(wheelRot);
            // 外のゴム
            ctx.fillStyle = COLOR.grey;
            ctx.beginPath();
            ctx.arc(0, 0, 45, 0, Math.PI * 2);
            ctx.fill();
            // ハブ
            ctx.fillStyle = COLOR.scarlet;
            ctx.beginPath();
            ctx.arc(0, 0, 25, 0, Math.PI * 2);
            ctx.fill();
            ctx.fillStyle = COLOR.cream;
            ctx.beginPath();
            ctx.arc(0, 0, 12, 0, Math.PI * 2);
            ctx.fill();
            ctx.restore();

            // 5. 【前肢 (Front Leg)】
            ctx.save();
            ctx.translate(65, 20);
            if (currentPose === 'flight') {
                ctx.rotate(Math.PI / 2.5); // 後ろになびく
            } else if (currentPose === 'glow') {
                ctx.rotate(-Math.PI / 12);
            }
            // 肩
            let shoulderGrad = ctx.createRadialGradient(-5, -5, 5, 0, 0, 35);
            shoulderGrad.addColorStop(0, COLOR.scarletLight);
            shoulderGrad.addColorStop(1, COLOR.scarlet);
            ctx.fillStyle = shoulderGrad;
            ctx.beginPath();
            ctx.ellipse(0, 0, 28, 40, -Math.PI / 8, 0, Math.PI * 2);
            ctx.fill();
            // 肩の稲妻マーク
            drawLightningMark(ctx, -10, -5, 14, Math.PI / 8);

            // 腕・前脚
            ctx.fillStyle = COLOR.scarlet;
            ctx.beginPath();
            ctx.ellipse(5, 38, 16, 28, Math.PI / 12, 0, Math.PI * 2);
            ctx.fill();
            // 爪
            ctx.fillStyle = COLOR.cream;
            for (let i = 0; i < 3; i++) {
                ctx.beginPath();
                ctx.arc(10 + i * 8, 62, 6, 0, Math.PI, true);
                ctx.closePath();
                ctx.fill();
            }
            ctx.restore();

            // 6. 【巨大な胸部タイヤ (Chest Wheel)】
            ctx.save();
            ctx.translate(55, 35);
            let chestWheelRot = 0;
            if (currentPose === 'stand') {
                chestWheelRot = t * 0.4;
            } else if (currentPose === 'flight') {
                chestWheelRot = t * 9.0; // 超高速回転!
            } else if (currentPose === 'glow') {
                chestWheelRot = t * 2.0;
            }
            ctx.rotate(chestWheelRot);

            // 外側の黒いゴムタイヤ
            ctx.fillStyle = COLOR.grey;
            ctx.beginPath();
            ctx.arc(0, 0, 68, 0, Math.PI * 2);
            ctx.fill();

            // タイヤのトレッド(外側のボコボコトゲトゲ)
            ctx.fillStyle = COLOR.grey;
            for (let i = 0; i < 10; i++) {
                let angle = (i / 10) * Math.PI * 2;
                ctx.save();
                ctx.rotate(angle);
                ctx.beginPath();
                ctx.moveTo(63, -12);
                ctx.lineTo(76, 0);
                ctx.lineTo(63, 12);
                ctx.closePath();
                ctx.fill();
                ctx.restore();
            }

            // 白い歯車(インナーホイール)
            ctx.fillStyle = COLOR.cream;
            ctx.beginPath();
            ctx.arc(0, 0, 48, 0, Math.PI * 2);
            ctx.fill();

            // 特徴的な赤のギザギザ・太陽星型マークを数学的パスで精密描画!
            ctx.fillStyle = COLOR.scarlet;
            ctx.beginPath();
            const points = 8;
            for (let i = 0; i < points * 2; i++) {
                let angle = (i / (points * 2)) * Math.PI * 2;
                let r = (i % 2 === 0) ? 46 : 22; // ギザギザの深さ
                ctx.lineTo(Math.cos(angle) * r, Math.sin(angle) * r);
            }
            ctx.closePath();
            ctx.fill();

            // 中央の赤いハブ
            ctx.fillStyle = COLOR.scarlet;
            ctx.beginPath();
            ctx.arc(0, 0, 18, 0, Math.PI * 2);
            ctx.fill();
            ctx.fillStyle = COLOR.cream;
            ctx.beginPath();
            ctx.arc(0, 0, 8, 0, Math.PI * 2);
            ctx.fill();

            ctx.restore();

            // 7. 【首 (Neck)】
            ctx.save();
            ctx.translate(headX - 10, headY + 30);
            ctx.rotate(-0.25 + Math.sin(t * 3.5) * 0.03);
            let neckGrad = ctx.createLinearGradient(-25, -25, 25, 25);
            neckGrad.addColorStop(0, COLOR.scarletLight);
            neckGrad.addColorStop(1, COLOR.scarlet);
            ctx.fillStyle = neckGrad;
            ctx.beginPath();
            ctx.ellipse(0, 0, 22, 45, Math.PI / 4, 0, Math.PI * 2);
            ctx.fill();

            // ディープブルーの肩ケープマント
            ctx.fillStyle = COLOR.blue;
            ctx.beginPath();
            ctx.ellipse(-15, 20, 20, 35, Math.PI / 3, 0, Math.PI * 2);
            ctx.fill();
            ctx.restore();

            // 8. 【頭部グループ (Head Group)】
            ctx.save();
            ctx.translate(headX, headY);
            ctx.rotate(headRotation);

            // 頭のベース
            let headGrad = ctx.createRadialGradient(-10, -10, 5, 0, 0, 40);
            headGrad.addColorStop(0, COLOR.scarletLight);
            headGrad.addColorStop(1, COLOR.scarlet);
            ctx.fillStyle = headGrad;
            ctx.beginPath();
            ctx.ellipse(0, 0, 38, 30, 0, 0, Math.PI * 2);
            ctx.fill();

            // 口先(アゴ)
            ctx.fillStyle = COLOR.scarlet;
            ctx.beginPath();
            ctx.moveTo(10, -15);
            ctx.lineTo(45, 5);
            
            // 咆哮モードなら大きく口を開ける!
            if (currentPose === 'glow') {
                ctx.lineTo(25, 32);
                ctx.lineTo(0, 12);
            } else {
                ctx.lineTo(25, 12);
                ctx.lineTo(0, 8);
            }
            ctx.closePath();
            ctx.fill();

            // アゴの白いひげ飾り
            ctx.fillStyle = COLOR.cream;
            ctx.beginPath();
            ctx.ellipse(15, 18, 15, 8, -Math.PI / 12, 0, Math.PI * 2);
            ctx.fill();

            // 青いトサカ(王冠風)
            ctx.fillStyle = COLOR.blue;
            ctx.beginPath();
            ctx.moveTo(-15, -25);
            ctx.lineTo(-5, -45);
            ctx.lineTo(5, -25);
            ctx.lineTo(20, -38);
            ctx.lineTo(22, -15);
            ctx.closePath();
            ctx.fill();

            // 眉元の赤いトゲ
            ctx.fillStyle = COLOR.scarlet;
            ctx.beginPath();
            ctx.moveTo(15, -20);
            ctx.lineTo(35, -28);
            ctx.lineTo(25, -10);
            ctx.closePath();
            ctx.fill();

            // 【瞳 (Eye - 二重構造のうるみ表現)】
            ctx.save();
            ctx.translate(14, -6);
            // 白目(オレンジ)
            ctx.fillStyle = COLOR.gold;
            ctx.beginPath();
            ctx.ellipse(0, 0, 14, 10, -Math.PI / 12, 0, Math.PI * 2);
            ctx.fill();

            // 黒目(瞳孔)
            ctx.fillStyle = COLOR.pupil;
            ctx.beginPath();
            ctx.ellipse(3, 0, 7, 7, 0, 0, Math.PI * 2);
            ctx.fill();

            // ハイライト(白)
            ctx.fillStyle = COLOR.white;
            ctx.beginPath();
            ctx.arc(5, -3, 3, 0, Math.PI * 2);
            ctx.fill();
            ctx.restore();

            // 【超ロング・うねうねリボンアンテナ】
            // 頭の後ろから優雅にうねって背中に垂れるグラデーション付きロングアンテナ
            ctx.save();
            ctx.translate(-20, -5);
            
            let ribbonSegments = 16;
            for (let i = 0; i < ribbonSegments; i++) {
                // セグメントを重ねることで、うねうねした有機的な厚みを完全表現
                ctx.translate(-12, 5 + Math.sin(t * 4 + i * 0.4) * 2.5);
                ctx.rotate(-0.06 + Math.cos(t * 3.5 + i * 0.3) * 0.04);
                
                // グラデーション色(根元はビビッドマゼンタピンク、先端は白)
                let segColor = COLOR.cream;
                if (i < 4) {
                    segColor = COLOR.magenta;
                } else if (i < 8) {
                    segColor = COLOR.white;
                }

                ctx.fillStyle = segColor;
                ctx.beginPath();
                // 扁平な節
                ctx.ellipse(0, 0, 15 - i * 0.6, 6 - i * 0.2, Math.PI / 12, 0, Math.PI * 2);
                ctx.fill();
            }
            ctx.restore();

            ctx.restore(); // 頭部グループ復帰
            ctx.restore(); // 親グループ復帰
        }

        // ----------------------------------------------------
        // --- 咆哮(ほうこう)エフェクト発生処理 ---
        // ----------------------------------------------------
        function triggerRoarEffect() {
            roarRings.push({
                x: canvas.width / (2 * (window.devicePixelRatio || 1)) + 100 * koraidonScaleFactor(),
                y: canvas.height / (2 * (window.devicePixelRatio || 1)) - 130 * koraidonScaleFactor(),
                radius: 10,
                maxRadius: 180 + Math.random() * 120,
                opacity: 1.0,
                color: COLOR.magenta
            });
            // 2層目
            setTimeout(() => {
                roarRings.push({
                    x: canvas.width / (2 * (window.devicePixelRatio || 1)) + 100 * koraidonScaleFactor(),
                    y: canvas.height / (2 * (window.devicePixelRatio || 1)) - 130 * koraidonScaleFactor(),
                    radius: 10,
                    maxRadius: 220,
                    opacity: 0.8,
                    color: COLOR.gold
                });
            }, 150);
        }

        // 画面幅からスケーリング比を算出
        function koraidonScaleFactor() {
            let scale = 1.25;
            if (window.innerWidth < 640) {
                scale = 0.85; // スマホ
            } else if (window.innerWidth < 1024) {
                scale = 1.05; // タブレット
            }
            return scale;
        }

        // ----------------------------------------------------
        // --- メインループ & レンダリング ---
        // ----------------------------------------------------
        function drawStage(timestamp) {
            if (!lastTime) lastTime = timestamp;
            const dt = (timestamp - lastTime) / 1000;
            lastTime = timestamp;
            
            // アニメーション用時間を蓄積
            totalTime += dt * speedMultiplier;

            // 描画領域をクリア(デバイス比率を考慮した実際の論理ピクセル範囲)
            const w = window.innerWidth;
            const h = window.innerHeight;
            ctx.clearRect(0, 0, w, h);

            // 1. 【背景ステージの描画】
            let bgGrad = ctx.createLinearGradient(0, 0, 0, h);
            if (currentBgStage === 'day') {
                bgGrad.addColorStop(0, '#0f172a'); // さわやかな宇宙ブルー
                bgGrad.addColorStop(0.6, '#1e1b4b');
                bgGrad.addColorStop(1, '#311042');
            } else if (currentBgStage === 'sunset') {
                bgGrad.addColorStop(0, '#2e1035'); // 燃えるような夕空
                bgGrad.addColorStop(0.5, '#7c2d12');
                bgGrad.addColorStop(1, '#f97316');
            } else if (currentBgStage === 'night') {
                bgGrad.addColorStop(0, '#030712'); // 深い夜空
                bgGrad.addColorStop(0.6, '#0b0f19');
                bgGrad.addColorStop(1, '#111827');
            }
            ctx.fillStyle = bgGrad;
            ctx.fillRect(0, 0, w, h);

            // 2. 【飛行モード時の流れる光(スピードライン)】
            if (currentPose === 'flight') {
                ctx.strokeStyle = 'rgba(255, 255, 255, 0.12)';
                ctx.lineWidth = 2;
                for (let i = 0; i < 8; i++) {
                    let lineY = ((totalTime * 800 + i * 200) % h);
                    ctx.beginPath();
                    ctx.moveTo(0, lineY);
                    ctx.lineTo(w, lineY - 150);
                    ctx.stroke();
                }
            }

            // 3. 【浮遊する粒子エフェクト】
            particles.forEach(p => {
                p.y -= p.speedY * speedMultiplier * effectsIntensity;
                p.x += Math.sin(totalTime + p.size) * 0.0005;

                if (p.y < 0) {
                    p.y = 1.0;
                    p.x = Math.random();
                }

                ctx.fillStyle = (currentBgStage === 'sunset') ? 'rgba(249, 115, 22, 0.5)' : 'rgba(239, 68, 68, 0.5)';
                ctx.beginPath();
                ctx.arc(p.x * w, p.y * h, p.size * effectsIntensity, 0, Math.PI * 2);
                ctx.fill();
            });

            // 4. 【お立ち台プレート (展示スタンド)】
            const cx = w / 2;
            const cy = h / 2 + 100;

            ctx.save();
            ctx.shadowBlur = 30;
            ctx.shadowColor = 'rgba(239, 68, 68, 0.4)';
            
            let stageGrad = ctx.createRadialGradient(cx, cy, 10, cx, cy, 320);
            stageGrad.addColorStop(0, '#111625');
            stageGrad.addColorStop(0.8, '#090d16');
            stageGrad.addColorStop(1, 'rgba(15, 23, 42, 0)');
            
            ctx.fillStyle = stageGrad;
            ctx.beginPath();
            ctx.ellipse(cx, cy, 340, 100, 0, 0, Math.PI * 2);
            ctx.fill();
            ctx.restore();

            // 5. 【コライドン本体の描画】
            let koraidonScale = koraidonScaleFactor();
            drawKoraidon(ctx, cx - 40 * koraidonScale, cy - 10 * koraidonScale, koraidonScale, totalTime);

            // 6. 【咆哮音波リングの描画】
            roarRings.forEach((ring, index) => {
                ring.radius += 5 * speedMultiplier;
                ring.opacity = 1 - (ring.radius / ring.maxRadius);

                if (ring.radius >= ring.maxRadius) {
                    roarRings.splice(index, 1);
                } else {
                    ctx.save();
                    ctx.strokeStyle = ring.color;
                    ctx.globalAlpha = ring.opacity;
                    ctx.lineWidth = 4 * effectsIntensity;
                    ctx.shadowBlur = 15;
                    ctx.shadowColor = ring.color;
                    ctx.beginPath();
                    ctx.arc(ring.x, ring.y, ring.radius, 0, Math.PI * 2);
                    ctx.stroke();
                    ctx.restore();
                }
            });

            // 咆哮モード中は定期的(0.3秒おき)に自動でリングエフェクトを射出
            if (currentPose === 'glow' && Math.floor(totalTime * 3) % 4 === 0 && roarRings.length < 5) {
                triggerRoarEffect();
            }

            requestAnimationFrame(drawStage);
        }

        // ----------------------------------------------------
        // --- モバイル&デスクトップ共通:スワイプ(回転)とタップ判定 ---
        // ----------------------------------------------------
        function setupTouchHandlers() {
            // ドラッグ開始
            function handleStart(clientX) {
                isDragging = true;
                startX = clientX;
                unlockAudio(); // 最初のタップでWebAudioロックを解除
            }

            // ドラッグ中(左右スワイプでコライドン回転)
            function handleMove(clientX) {
                if (!isDragging) return;
                const deltaX = clientX - startX;
                koraidonRotateY += deltaX * 0.007; // スピード調整
                startX = clientX;
            }

            // ドラッグ終了(簡易タップ判定)
            function handleEnd() {
                isDragging = false;
            }

            // タップして「ほえる!」を発動
            function handleTap(clientX, clientY) {
                // クイズ表示中、またはUIコントロールを触っている時は動作させない
                if (document.getElementById('quiz-window').classList.contains('hidden') === false) return;
                
                // コライドンがいると思われる画面中央付近
                const cx = window.innerWidth / 2;
                const cy = window.innerHeight / 2;
                const dist = Math.hypot(clientX - cx, clientY - cy);
                
                // コライドンを直接タッチした場合に「ほえる」ポーズを発動
                if (dist < 150 * koraidonScaleFactor()) {
                    clearPoseBtnStyles();
                    document.getElementById('pose-glow').className = "bg-amber-500 hover:bg-amber-400 text-white py-2.5 px-1 rounded-xl font-bold transition duration-200 text-xs animate-pulse";
                    currentPose = 'glow';
                    triggerRoarEffect();
                    playSystemSound(150, 'sawtooth', 0.3);
                }
            }

            // マウスイベント
            canvas.addEventListener('mousedown', (e) => {
                handleStart(e.clientX);
            });
            window.addEventListener('mousemove', (e) => {
                handleMove(e.clientX);
            });
            window.addEventListener('mouseup', () => {
                handleEnd();
            });
            canvas.addEventListener('click', (e) => {
                handleTap(e.clientX, e.clientY);
            });

            // タッチイベント
            canvas.addEventListener('touchstart', (e) => {
                if (e.touches.length === 1) {
                    handleStart(e.touches[0].clientX);
                }
            }, { passive: true });
            
            canvas.addEventListener('touchmove', (e) => {
                if (e.touches.length === 1) {
                    handleMove(e.touches[0].clientX);
                }
            }, { passive: true });
            
            canvas.addEventListener('touchend', (e) => {
                handleEnd();
                if (e.changedTouches.length === 1) {
                    // タップとして判定
                    handleTap(e.changedTouches[0].clientX, e.changedTouches[0].clientY);
                }
            }, { passive: true });
        }

        // 初期化実行
        document.addEventListener('DOMContentLoaded', () => {
            // UI表示
            setTimeout(() => {
                document.getElementById('ui-overlay').classList.remove('opacity-0');
            }, 100);

            // ループ&操作の初期化
            setupTouchHandlers();
            requestAnimationFrame(drawStage);
        });

    </script>

    <!-- UI INTERACTIVE BINDINGS & POKEAPI QUIZ -->
    <script>
        // --- 調整スライダーバインディング ---
        document.getElementById('slider-speed').addEventListener('input', (e) => {
            speedMultiplier = parseFloat(e.target.value);
            document.getElementById('val-speed').textContent = speedMultiplier.toFixed(1) + 'x';
        });

        const sliderEffects = document.getElementById('slider-effects');
        if (sliderEffects) {
            sliderEffects.addEventListener('input', (e) => {
                effectsIntensity = parseFloat(e.target.value);
                document.getElementById('val-effects').textContent = effectsIntensity.toFixed(1) + 'x';
            });
        }

        // --- ポーズ切り替えイベント ---
        const btnStand = document.getElementById('pose-stand');
        const btnFlight = document.getElementById('pose-flight');
        const btnGlow = document.getElementById('pose-glow');

        function clearPoseBtnStyles() {
            [btnStand, btnFlight, btnGlow].forEach(btn => {
                btn.className = "bg-slate-900 hover:bg-slate-800 text-slate-300 py-2.5 px-1 rounded-xl font-bold transition duration-200 text-xs";
            });
        }

        btnStand.addEventListener('click', () => {
            clearPoseBtnStyles();
            btnStand.className = "bg-rose-600 hover:bg-rose-500 text-white py-2.5 px-1 rounded-xl font-bold transition duration-200 shadow-md text-xs";
            currentPose = 'stand';
            playSystemSound(440, 'sine', 0.1);
        });

        btnFlight.addEventListener('click', () => {
            clearPoseBtnStyles();
            btnFlight.className = "bg-sky-600 hover:bg-sky-500 text-white py-2.5 px-1 rounded-xl font-bold transition duration-200 shadow-md text-xs";
            currentPose = 'flight';
            playSystemSound(554, 'triangle', 0.15);
        });

        btnGlow.addEventListener('click', () => {
            clearPoseBtnStyles();
            btnGlow.className = "bg-amber-500 hover:bg-amber-400 text-white py-2.5 px-1 rounded-xl font-bold transition duration-200 shadow-md text-xs animate-pulse";
            currentPose = 'glow';
            triggerRoarEffect();
            playSystemSound(150, 'sawtooth', 0.3); // 咆哮っぽいうなり音
        });

        // 背景切り替えボタンのバインディング
        document.querySelectorAll('.btn-bg-stage').forEach(btn => {
            btn.addEventListener('click', (e) => {
                currentBgStage = btn.getAttribute('data-bg');
                playSystemSound(659, 'sine', 0.05);
            });
        });

        // 音声オンオフ切り替え
        const soundBtn = document.getElementById('btn-sound-toggle');
        const soundIcon = document.getElementById('sound-icon');
        soundBtn.addEventListener('click', () => {
            speakEnabled = !speakEnabled;
            if (speakEnabled) {
                soundIcon.className = "fa-solid fa-volume-high text-lg text-emerald-400";
                playSystemSound(440, 'sine', 0.08);
            } else {
                soundIcon.className = "fa-solid fa-volume-xmark text-lg text-rose-500";
            }
        });

        // モバイル(iOSなど)のセキュリティロック解除用関数
        function unlockAudio() {
            if (audioUnlocked) return;
            try {
                // ダミーのWebAudioを一度再生してブラウザの音声を解放する
                const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
                const buffer = audioCtx.createBuffer(1, 1, 22050);
                const source = audioCtx.createBufferSource();
                source.buffer = buffer;
                source.connect(audioCtx.destination);
                source.start();
                
                // 空のテキストスピーチを発行して音声合成も解放
                if ('speechSynthesis' in window) {
                    const u = new SpeechSynthesisUtterance("");
                    window.speechSynthesis.speak(u);
                }
                
                audioUnlocked = true;
                console.log("Web Audio & SpeechSynthesis Unlocked.");
            } catch (e) {
                console.log("Audio unlock failed:", e);
            }
        }

        // おんせいごうせい & 効果音
        function playSystemSound(freq, type, duration) {
            if (!speakEnabled) return;
            try {
                const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
                const osc = audioCtx.createOscillator();
                const gain = audioCtx.createGain();
                
                osc.type = type || 'sine';
                osc.frequency.setValueAtTime(freq, audioCtx.currentTime);
                
                gain.gain.setValueAtTime(0.15, audioCtx.currentTime);
                gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + duration);
                
                osc.connect(gain);
                gain.connect(audioCtx.destination);
                
                osc.start();
                osc.stop(audioCtx.currentTime + duration);
            } catch (e) {
                console.log("Audio failed to play");
            }
        }

        // ----------------------------------------------------
        // --- PokeAPI クイズシステム ---
        // ----------------------------------------------------
        const TYPE_JA = {
            normal: "ノーマル", fire: "ほのお", water: "みず", grass: "くさ",
            electric: "でんき", ice: "こおり", fighting: "かくとう", poison: "どく",
            ground: "じめん", flying: "ひこう", psychic: "エスパー", bug: "むし",
            rock: "いわ", ghost: "ゴースト", dragon: "ドラゴン", steel: "はがね",
            fairy: "フェアリー", dark: "あく"
        };

        const QuizGame = {
            score: 0,
            currentCorrect: null,

            init: function() {
                document.getElementById('btn-quiz-open').addEventListener('click', () => {
                    document.getElementById('quiz-window').classList.remove('hidden');
                    this.loadNewQuestion();
                });
                document.getElementById('btn-quiz-close').addEventListener('click', () => {
                    document.getElementById('quiz-window').classList.add('hidden');
                });
                document.getElementById('btn-next-quiz').addEventListener('click', () => {
                    this.loadNewQuestion();
                });
                document.getElementById('btn-quiz-retry').addEventListener('click', () => {
                    this.loadNewQuestion();
                });
            },

            showState: function(state) {
                ['loading', 'content', 'error', 'feedback'].forEach(s => {
                    document.getElementById('quiz-' + s).classList.add('hidden');
                });
                document.getElementById('quiz-' + state).classList.remove('hidden');
            },

            loadNewQuestion: async function() {
                this.showState('loading');
                document.getElementById('quiz-feedback').classList.add('hidden');
                
                const imgEl = document.getElementById('quiz-pokemon-img');
                imgEl.src = "";
                imgEl.className = "h-32 w-32 md:h-36 md:w-36 object-contain silhouette"; // 黒塗り(影絵)化

                try {
                    // 画像と日本語データが100%揃っている第1世代〜第7世代(1〜807番)からランダムに4つ用意
                    const ids = [];
                    while(ids.length < 4) {
                        const rid = Math.floor(Math.random() * 807) + 1;
                        if(!ids.includes(rid)) ids.push(rid);
                    }

                    // 4匹の基本データを同時読み込み
                    const details = await Promise.all(ids.map(id => 
                        fetch(`https://pokeapi.co/api/v2/pokemon/${id}`).then(r => {
                            if (!r.ok) throw new Error("APIエラー");
                            return r.json();
                        })
                    ));

                    this.currentCorrect = details[0];

                    // 種族名(日本語名)の取得
                    const speciesData = await fetch(this.currentCorrect.species.url).then(r => r.json());
                    this.currentCorrect.nameJa = speciesData.names.find(n => n.language.name === "ja-Hrkt")?.name 
                                             || speciesData.names.find(n => n.language.name === "ja")?.name 
                                             || this.currentCorrect.name;

                    // 他の3つのハズレ選択肢
                    const optionNames = [this.currentCorrect.nameJa];
                    for (let i = 1; i < 4; i++) {
                        const sData = await fetch(details[i].species.url).then(r => r.json());
                        const nameJa = sData.names.find(n => n.language.name === "ja-Hrkt")?.name || details[i].name;
                        optionNames.push(nameJa);
                    }

                    // 選択肢のシャッフル
                    optionNames.sort(() => Math.random() - 0.5);

                    // ヒント情報の登録
                    document.getElementById('quiz-pokemon-type').textContent = this.currentCorrect.types.map(t => TYPE_JA[t.type.name] || t.type.name).join(' ・ ');
                    document.getElementById('quiz-pokemon-weight').textContent = `${(this.currentCorrect.weight / 10).toFixed(1)} kg`;

                    // 公式高画質イラストをバインド
                    const spriteUrl = this.currentCorrect.sprites.other['official-artwork'].front_default 
                                   || this.currentCorrect.sprites.front_default;
                    
                    // ロード完了時に描画
                    const tempImg = new Image();
                    tempImg.src = spriteUrl;
                    tempImg.onload = () => {
                        imgEl.src = spriteUrl;
                        
                        // 選択肢ボタンの動的生成
                        const optContainer = document.getElementById('quiz-options');
                        optContainer.innerHTML = '';
                        optionNames.forEach((name, idx) => {
                            const btn = document.createElement('button');
                            btn.className = "quiz-opt-btn bg-slate-900 hover:bg-slate-800 p-2.5 md:p-3 rounded-xl font-bold text-xs md:text-sm text-left truncate flex items-center gap-1.5 border-2 border-slate-800 active:scale-95 transition-transform";
                            
                            const colorBadge = ['red', 'blue', 'yellow', 'green'][idx];
                            btn.innerHTML = `<span class="bg-${colorBadge}-500 text-white w-5 h-5 rounded-full inline-flex items-center justify-center text-xs font-black">${idx+1}</span> <span class="opt-text">${name}</span>`;
                            btn.onclick = () => this.checkAnswer(name, btn);
                            optContainer.appendChild(btn);
                        });

                        this.showState('content');
                    };

                } catch (err) {
                    console.error("Quiz Fetch Failed", err);
                    this.showState('error');
                }
            },

            checkAnswer: function(selectedName, clickedBtn) {
                const imgEl = document.getElementById('quiz-pokemon-img');
                const feedbackEl = document.getElementById('quiz-feedback');
                const feedbackText = document.getElementById('feedback-text');

                // 他の全ボタンを操作不可&透明化
                document.querySelectorAll('.quiz-opt-btn').forEach(btn => {
                    btn.classList.add('pointer-events-none', 'opacity-50');
                });

                // シルエット(黒塗り)を解除
                imgEl.classList.remove('silhouette');
                feedbackEl.classList.remove('hidden');

                const isCorrect = selectedName === this.currentCorrect.nameJa;

                if (isCorrect) {
                    this.score += 10;
                    document.getElementById('score-val').textContent = this.score;
                    feedbackEl.className = "mt-3 p-3 rounded-xl font-bold text-sm bg-emerald-500/30 text-emerald-300 border-emerald-500 border-2 text-center";
                    feedbackText.innerHTML = `<i class="fa-solid fa-circle-check text-lg mr-1 text-emerald-400"></i> せいかい! +10点!<br>あたまのなかで「${this.currentCorrect.nameJa}」をよんだよ!`;
                    
                    clickedBtn.className = "quiz-opt-btn bg-emerald-950 border-emerald-500 p-2.5 md:p-3 rounded-xl font-bold text-xs md:text-sm text-left truncate flex items-center gap-1.5 border-2 text-emerald-300";
                    clickedBtn.classList.remove('opacity-50');
                    playSystemSound(880, 'sine', 0.2);
                } else {
                    feedbackEl.className = "mt-3 p-3 rounded-xl font-bold text-sm bg-red-500/30 text-red-300 border-red-500 border-2 text-center";
                    feedbackText.innerHTML = `<i class="fa-solid fa-circle-xmark text-lg mr-1 text-red-400"></i> ざんねん!ちがうよ!<br>せいかいは <strong>${this.currentCorrect.nameJa}</strong> でした!`;
                    
                    clickedBtn.className = "quiz-opt-btn bg-red-950 border-red-500 p-2.5 md:p-3 rounded-xl font-bold text-xs md:text-sm text-left truncate flex items-center gap-1.5 border-2 text-red-300";
                    clickedBtn.classList.remove('opacity-50');

                    // 正解ボタンをハイライト
                    document.querySelectorAll('.quiz-opt-btn').forEach(btn => {
                        if (btn.querySelector('.opt-text').textContent === this.currentCorrect.nameJa) {
                            btn.className = "quiz-opt-btn bg-emerald-950 border-emerald-500 p-2.5 md:p-3 rounded-xl font-bold text-xs md:text-sm text-left truncate flex items-center gap-1.5 border-2 text-emerald-300";
                            btn.classList.remove('opacity-50');
                        }
                    });
                    playSystemSound(220, 'sawtooth', 0.25);
                }

                // ポケモン名読み上げ(音声)
                speakPokemonName(this.currentCorrect.nameJa);
            }
        };

        function speakPokemonName(name) {
            if (speakEnabled && 'speechSynthesis' in window) {
                window.speechSynthesis.cancel();
                const u = new SpeechSynthesisUtterance(name);
                u.lang = 'ja-JP';
                u.rate = 1.05;
                window.speechSynthesis.speak(u);
            }
        }

        // クイズ初期化
        QuizGame.init();

    </script>
</body>
</html>

ポケモンクイズ

by ryusei

ポケモンのクイズです!

👁 27 回閲覧
📅 投稿:2026年6月6日 🔄 更新:2026年8月13日
応援スタンプを押してみよう!