🎮ArcadeLab

🌌 CMB PURIFIER - پالایشگر تابش زمینه کیهانی

by RapidKnight54
718 lines27.6 KB
▶ Play
<!DOCTYPE html>
<html lang="fa">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>🌌 CMB PURIFIER - پالایشگر تابش زمینه کیهانی</title>
    <style>
        * {
            user-select: none;
            touch-action: none;
        }

        body {
            margin: 0;
            min-height: 100vh;
            background: linear-gradient(135deg, #000000 0%, #0a0a2a 100%);
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Orbitron', 'Courier New', monospace;
            padding: 15px;
            overflow: hidden;
            position: fixed;
            width: 100%;
            height: 100%;
        }

        @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&display=swap');

        .game-wrapper {
            max-width: 900px;
            width: 100%;
            position: relative;
        }

        canvas {
            display: block;
            width: 100%;
            height: auto;
            background: radial-gradient(ellipse at center, #0a0a2a 0%, #000000 100%);
            border-radius: 30px;
            box-shadow: 0 0 40px rgba(0, 255, 255, 0.5), 0 0 20px rgba(255, 0, 255, 0.3);
            cursor: none;
            touch-action: none;
        }

        .hud {
            display: flex;
            justify-content: space-between;
            align-items: center;
            background: rgba(0, 0, 0, 0.85);
            backdrop-filter: blur(15px);
            padding: 12px 20px;
            border-radius: 50px;
            margin-bottom: 15px;
            border: 1px solid rgba(0, 255, 255, 0.5);
            flex-wrap: wrap;
            gap: 10px;
        }

        .stat-card {
            background: rgba(0,0,0,0.6);
            padding: 5px 15px;
            border-radius: 30px;
            text-align: center;
            border-left: 3px solid cyan;
        }

        .stat-card span {
            font-size: 0.65rem;
            color: #88aaff;
        }

        .stat-card div {
            font-size: 1.4rem;
            font-weight: bold;
            color: #ffd700;
            text-shadow: 0 0 5px orange;
        }

        .hearts {
            display: flex;
            gap: 8px;
            font-size: 1.8rem;
        }

        button {
            background: linear-gradient(135deg, #ff416c, #ff4b2b);
            border: none;
            padding: 8px 18px;
            border-radius: 30px;
            font-family: 'Orbitron', monospace;
            font-weight: bold;
            font-size: 0.8rem;
            color: white;
            cursor: pointer;
            transition: all 0.2s;
        }

        button:active {
            transform: scale(0.95);
        }

        .upgrade-panel {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: rgba(0,0,0,0.95);
            backdrop-filter: blur(10px);
            padding: 15px;
            border-radius: 25px;
            border: 1px solid #00ffff;
            min-width: 200px;
            z-index: 100;
            font-size: 0.7rem;
        }

        .upgrade-panel h4 {
            margin: 0 0 10px 0;
            color: #00ffff;
            text-align: center;
        }

        .upgrade-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 8px 0;
            gap: 10px;
        }

        .upgrade-item button {
            padding: 4px 12px;
            font-size: 0.7rem;
            background: #1a3a5c;
        }

        .damage-number {
            position: absolute;
            pointer-events: none;
            font-weight: bold;
            font-size: 1rem;
            animation: floatUp 0.6s ease-out forwards;
            z-index: 200;
            text-shadow: 0 0 5px cyan;
        }

        @keyframes floatUp {
            0% { opacity: 1; transform: translateY(0px) scale(0.8); }
            100% { opacity: 0; transform: translateY(-50px) scale(1.2); }
        }

        .game-over-modal {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(0,0,0,0.98);
            padding: 30px;
            border-radius: 50px;
            text-align: center;
            border: 3px solid cyan;
            z-index: 300;
            min-width: 280px;
            backdrop-filter: blur(20px);
        }

        .hidden {
            display: none;
        }

        .cmb-badge {
            position: absolute;
            top: 10px;
            left: 20px;
            font-size: 0.6rem;
            color: cyan;
            background: rgba(0,0,0,0.5);
            padding: 4px 12px;
            border-radius: 20px;
            pointer-events: none;
        }

        @media (max-width: 700px) {
            .upgrade-panel { display: none; }
            .stat-card div { font-size: 1rem; }
            .hearts { font-size: 1.2rem; }
        }
    </style>
</head>
<body>
<div class="game-wrapper">
    <div class="cmb-badge">🌡️ CMB: 2.725 K | ناهمسانی: فعال</div>
    <div class="hud">
        <div class="stat-card">🌡️ <span>یکنواختی</span><div id="scoreVal">0</div></div>
        <div class="stat-card">🏆 <span>رکورد CMB</span><div id="highScoreVal">0</div></div>
        <div class="hearts" id="heartsDisplay">🔴 🔴 🔴 🔴 🔴</div>
        <div class="stat-card">💥 <span>ناهمسانی‌ها</span><div id="killCountVal">0</div></div>
        <div class="stat-card">⚡ <span>انرژی کیهانی</span><div id="moneyVal">0</div></div>
    </div>
    
    <canvas id="gameCanvas" width="800" height="550"></canvas>
    
    <div style="display: flex; gap: 10px; margin-top: 12px; justify-content: center;">
        <button id="restartGameBtn">🌀 بازنشانی کیهان</button>
        <button id="toggleUpgradeBtn" style="background: linear-gradient(135deg, #00aaff, #0066cc);">🔬 ارتقای طیف‌سنج</button>
    </div>
    
    <div class="upgrade-panel hidden" id="upgradePanel">
        <h4>🔭 ارتقای تجهیزات CMB</h4>
        <div class="upgrade-item">🌡️ قدرت یکسان‌سازی <button id="upgradeDmg">+ (💰50)</button></div>
        <div class="upgrade-item">⚡ سرعت طیف‌سنج <button id="upgradeSpeed">+ (💰80)</button></div>
        <div class="upgrade-item">❤️ سنسور حیاتی <button id="upgradeLife">+ (💰120)</button></div>
        <div class="upgrade-item">💫 شانس بحرانی <button id="upgradeCrit">+ (💰100)</button></div>
        <div style="margin-top:10px; font-size:0.65rem; color:#88aaff; text-align:center;">📡 تصفیه‌ی ناهمسانی‌ها</div>
    </div>
    
    <div id="gameOverModal" class="game-over-modal hidden">
        <h2>🌌 CMB نامتعادل شد 🌌</h2>
        <p id="finalStats"></p>
        <button id="playAgainModalBtn">🌀 دوباره تصفیه کن</button>
    </div>
</div>

<script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    
    canvas.width = 800;
    canvas.height = 550;
    
    // ========== وضعیت بازی ==========
    let gameRunning = true;
    let animationId;
    
    // سفینه‌ی تصفیه‌گر (پالایشگر CMB)
    let player = {
        x: canvas.width/2,
        y: canvas.height - 60,
        radius: 18,
        lives: 5,
        maxLives: 5
    };
    
    // آمار
    let isotropyScore = 0;  // میزان یکنواختی (امتیاز)
    let highScore = localStorage.getItem('cmbPurifierHigh') ? parseInt(localStorage.getItem('cmbPurifierHigh')) : 0;
    let anomaliesDestroyed = 0;  // ناهمسانی‌های نابود شده
    let cosmicEnergy = 0;  // انرژی کیهانی (پول)
    
    // آپگریدها
    let upgrades = {
        purificationPower: 1.0,   // قدرت یکسان‌سازی
        spectrometerSpeed: 1.0,  // سرعت طیف‌سنج
        critChance: 0.1,         // شانس بحرانی
        extraLives: 0
    };
    
    let upgradeCost = { dmg: 50, speed: 80, life: 120, crit: 100 };
    
    // ناهمسانی‌ها (دشمنان)
    let anomalies = [];
    let purificationBeams = [];  // پرتوهای یکسان‌سازی (گلوله‌ها)
    let particles = [];
    
    let lastShot = 0;
    let shootDelay = 250;
    
    // باس فایت (ناهمسانی غول‌پیکر)
    let giantAnomaly = null;
    let giantAnomalyActive = false;
    let nextGiantAnomalyScore = 200;
    
    // ستاره‌های زمینه (نماد CMB)
    let stars = [];
    for(let i=0;i<200;i++) stars.push({ x:Math.random()*canvas.width, y:Math.random()*canvas.height, size:1+Math.random()*2 });
    
    // المان‌ها
    const scoreVal = document.getElementById('scoreVal');
    const highScoreVal = document.getElementById('highScoreVal');
    const heartsDisplay = document.getElementById('heartsDisplay');
    const killCountVal = document.getElementById('killCountVal');
    const moneyVal = document.getElementById('moneyVal');
    const restartBtn = document.getElementById('restartGameBtn');
    const toggleUpgradeBtn = document.getElementById('toggleUpgradeBtn');
    const upgradePanel = document.getElementById('upgradePanel');
    const gameOverModal = document.getElementById('gameOverModal');
    const playAgainModalBtn = document.getElementById('playAgainModalBtn');
    const finalStats = document.getElementById('finalStats');
    
    highScoreVal.innerText = highScore;
    
    // ========== کلاس ناهمسانی CMB ==========
    class CMBAnomaly {
        constructor(x, y, type, hp = 1) {
            this.x = x;
            this.y = y;
            this.type = type; // hot (نقطه داغ), cold (نقطه سرد), unstable (ناهمسانی ناپایدار)
            this.radius = 22;
            this.hp = hp;
            this.maxHp = hp;
            this.speedY = 1.0 + Math.random() * 1.3;
            this.speedX = (Math.random() - 0.5) * 0.7;
            if(type === 'hot') { this.speedY = 1.5; this.hp = 1; this.radius = 18; }
            if(type === 'cold') { this.speedY = 1.1; this.hp = 2; this.radius = 24; }
            if(type === 'unstable') { this.speedY = 0.6; this.hp = 4; this.radius = 32; }
        }
        
        update() {
            this.y += this.speedY;
            this.x += this.speedX;
            if(this.x - this.radius < 0) this.x = this.radius;
            if(this.x + this.radius > canvas.width) this.x = canvas.width - this.radius;
            return this.y + this.radius > canvas.height;
        }
        
        draw() {
            const pulse = 0.85 + Math.sin(Date.now() * 0.01) * 0.1;
            const gradient = ctx.createRadialGradient(this.x-5, this.y-5, 5, this.x, this.y, this.radius);
            if(this.type === 'hot') {
                gradient.addColorStop(0, '#ff6644');
                gradient.addColorStop(1, '#cc2200');
                ctx.fillStyle = gradient;
            } else if(this.type === 'cold') {
                gradient.addColorStop(0, '#4488ff');
                gradient.addColorStop(1, '#0044aa');
                ctx.fillStyle = gradient;
            } else {
                gradient.addColorStop(0, '#aa44ff');
                gradient.addColorStop(1, '#5511aa');
                ctx.fillStyle = gradient;
            }
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.radius * pulse, 0, Math.PI*2);
            ctx.fill();
            ctx.fillStyle = 'white';
            ctx.font = "bold 16px monospace";
            let icon = this.type === 'hot' ? '🌡️+' : (this.type === 'cold' ? '🌡️-' : '⚠️');
            ctx.fillText(icon, this.x-10, this.y+8);
            
            // نمایش HP برای ناهمسانی‌های قوی
            if(this.hp > 1) {
                ctx.fillStyle = '#ff4444';
                ctx.fillRect(this.x-18, this.y-22, 36, 5);
                ctx.fillStyle = '#00ff88';
                ctx.fillRect(this.x-18, this.y-22, 36 * (this.hp/this.maxHp), 5);
            }
        }
        
        takeDamage(amount) {
            let finalDmg = amount * upgrades.purificationPower;
            if(Math.random() < upgrades.critChance) {
                finalDmg *= 2.2;
                this.showDamage(`✨ ${finalDmg.toFixed(0)}! یکسان‌سازی بحرانی!`, true);
            } else {
                this.showDamage(`🌀 ${finalDmg.toFixed(0)}`, false);
            }
            this.hp -= finalDmg;
            return this.hp <= 0;
        }
        
        showDamage(msg, isCrit) {
            const div = document.createElement('div');
            div.className = 'damage-number';
            div.innerText = msg;
            div.style.color = isCrit ? '#ffff00' : '#66ffcc';
            div.style.fontSize = isCrit ? '1rem' : '0.9rem';
            div.style.left = (this.x + canvas.getBoundingClientRect().left - 30) + 'px';
            div.style.top = (this.y + canvas.getBoundingClientRect().top - 20) + 'px';
            div.style.position = 'fixed';
            document.body.appendChild(div);
            setTimeout(() => div.remove(), 500);
        }
    }
    
    // پرتو یکسان‌سازی (گلوله)
    class PurificationBeam {
        constructor(x, y) {
            this.x = x;
            this.y = y;
            this.radius = 6;
            this.speed = -7;
        }
        update() {
            this.y += this.speed;
            return this.y + this.radius < 0;
        }
        draw() {
            ctx.fillStyle = '#00ffff';
            ctx.shadowBlur = 12;
            ctx.shadowColor = '#00ffff';
            ctx.beginPath();
            ctx.arc(this.x, this.y, 6, 0, Math.PI*2);
            ctx.fill();
            ctx.fillStyle = '#ffffff';
            ctx.beginPath();
            ctx.arc(this.x, this.y, 3, 0, Math.PI*2);
            ctx.fill();
            ctx.shadowBlur = 0;
        }
    }
    
    function addExplosion(x,y, type='hot') {
        let color = type === 'hot' ? '#ff8844' : (type === 'cold' ? '#4488ff' : '#aa66ff');
        for(let i=0;i<12;i++) {
            particles.push({ 
                x: x + (Math.random()-0.5)*20, 
                y: y + (Math.random()-0.5)*20, 
                life: 1, 
                size: 2+Math.random()*5,
                color: color
            });
        }
    }
    
    // حرکت سفینه
    function movePlayer(e) {
        if(!gameRunning) return;
        const rect = canvas.getBoundingClientRect();
        const scaleX = canvas.width / rect.width;
        let clientX;
        if(e.touches) clientX = e.touches[0].clientX;
        else clientX = e.clientX;
        let canvasX = (clientX - rect.left) * scaleX;
        canvasX = Math.min(Math.max(canvasX, player.radius+10), canvas.width - player.radius-10);
        player.x = canvasX;
    }
    
    // شلیک پرتو یکسان‌سازی
    function shoot() {
        if(!gameRunning) return;
        let now = Date.now();
        let delay = shootDelay / upgrades.spectrometerSpeed;
        if(now - lastShot > delay) {
            purificationBeams.push(new PurificationBeam(player.x, player.y-12));
            lastShot = now;
        }
    }
    
    // اسپاون ناهمسانی CMB
    function spawnAnomaly() {
        if(!gameRunning) return;
        if(giantAnomalyActive) return;
        let rand = Math.random();
        let type = 'hot';
        if(isotropyScore > 300) type = rand<0.4 ? 'hot' : (rand<0.7 ? 'cold' : 'unstable');
        else if(isotropyScore > 100) type = rand<0.5 ? 'hot' : (rand<0.8 ? 'cold' : 'unstable');
        else type = rand<0.6 ? 'hot' : 'cold';
        
        let hp = 1;
        if(type === 'cold') hp = 2;
        if(type === 'unstable') hp = 3 + Math.floor(isotropyScore/300);
        
        let anomaly = new CMBAnomaly(30 + Math.random()*(canvas.width-60), -30, type, hp);
        anomalies.push(anomaly);
    }
    
    function updateGame() {
        if(!gameRunning) return;
        
        // اسپاون خودکار
        if(Math.random() < 0.025 + isotropyScore/6000 && anomalies.length < 14 && !giantAnomalyActive) spawnAnomaly();
        
        // ناهمسانی غول‌پیکر (باس فایت)
        if(isotropyScore >= nextGiantAnomalyScore && !giantAnomalyActive && !giantAnomaly) {
            giantAnomalyActive = true;
            giantAnomaly = { 
                x: canvas.width/2, y: 80, radius: 50, 
                hp: 30 + Math.floor(isotropyScore/60), 
                maxHp: 30 + Math.floor(isotropyScore/60), 
                type: 'giant', 
                moveDir: 1,
                phase: 1
            };
            anomalies = anomalies.filter(a => a.y < canvas.height-120);
        }
        
        // آپدیت ناهمسانی‌ها
        for(let i=0;i<anomalies.length;i++) {
            let isOut = anomalies[i].update();
            if(isOut) { anomalies.splice(i,1); i--; continue; }
            
            let dist = Math.hypot(player.x - anomalies[i].x, player.y - anomalies[i].y);
            if(dist < player.radius + anomalies[i].radius) {
                player.lives--;
                addExplosion(player.x, player.y, anomalies[i].type);
                anomalies.splice(i,1);
                updateHearts();
                if(player.lives <= 0) endGame();
                i--;
            }
        }
        
        // ناهمسانی غول‌پیکر (باس)
        if(giantAnomaly) {
            giantAnomaly.x += 2.5 * giantAnomaly.moveDir;
            if(giantAnomaly.x - giantAnomaly.radius < 30) giantAnomaly.moveDir = 1;
            if(giantAnomaly.x + giantAnomaly.radius > canvas.width-30) giantAnomaly.moveDir = -1;
            
            // افکت نوسانی
            const pulse = 0.9 + Math.sin(Date.now() * 0.005) * 0.1;
            ctx.beginPath();
            ctx.arc(giantAnomaly.x, giantAnomaly.y, giantAnomaly.radius * pulse, 0, Math.PI*2);
            const grad = ctx.createRadialGradient(giantAnomaly.x-10, giantAnomaly.y-10, 10, giantAnomaly.x, giantAnomaly.y, giantAnomaly.radius);
            grad.addColorStop(0, '#ff66aa');
            grad.addColorStop(1, '#aa00ff');
            ctx.fillStyle = grad;
            ctx.fill();
            ctx.fillStyle = 'white';
            ctx.font = "bold 22px Orbitron";
            ctx.fillText('🌀 ناهمسانی غول‌پیکر CMB', giantAnomaly.x-110, giantAnomaly.y-25);
            ctx.fillStyle = '#ff3333';
            ctx.fillRect(giantAnomaly.x-70, giantAnomaly.y-40, 140, 12);
            ctx.fillStyle = '#00ffaa';
            ctx.fillRect(giantAnomaly.x-70, giantAnomaly.y-40, 140 * (giantAnomaly.hp/giantAnomaly.maxHp), 12);
            
            // برخورد باس با بازیکن
            if(Math.hypot(player.x - giantAnomaly.x, player.y - giantAnomaly.y) < player.radius + giantAnomaly.radius) {
                player.lives -= 2;
                updateHearts();
                if(player.lives <= 0) endGame();
                giantAnomaly.hp -= 8;
                addExplosion(giantAnomaly.x, giantAnomaly.y, 'unstable');
            }
        }
        
        // پرتوها و برخورد
        for(let i=0;i<purificationBeams.length;i++) {
            if(purificationBeams[i].update()) { purificationBeams.splice(i,1); i--; continue; }
            let hit = false;
            
            for(let j=0;j<anomalies.length;j++) {
                if(Math.hypot(purificationBeams[i].x - anomalies[j].x, purificationBeams[i].y - anomalies[j].y) < purificationBeams[i].radius + anomalies[j].radius) {
                    let dead = anomalies[j].takeDamage(10);
                    purificationBeams.splice(i,1);
                    if(dead) {
                        let reward = 10 + (anomalies[j].type === 'cold' ? 8 : (anomalies[j].type === 'unstable' ? 20 : 5));
                        isotropyScore += reward;
                        cosmicEnergy += reward;
                        anomaliesDestroyed++;
                        addExplosion(anomalies[j].x, anomalies[j].y, anomalies[j].type);
                        anomalies.splice(j,1);
                        updateUI();
                    }
                    hit = true;
                    break;
                }
            }
            if(hit) { i--; continue; }
            
            // برخورد با باس
            if(giantAnomaly && Math.hypot(purificationBeams[i].x - giantAnomaly.x, purificationBeams[i].y - giantAnomaly.y) < purificationBeams[i].radius + giantAnomaly.radius) {
                let dmg = 12;
                giantAnomaly.hp -= dmg * upgrades.purificationPower;
                purificationBeams.splice(i,1);
                if(giantAnomaly.hp <= 0) {
                    let bonus = 120;
                    isotropyScore += bonus;
                    cosmicEnergy += bonus;
                    giantAnomaly = null;
                    giantAnomalyActive = false;
                    nextGiantAnomalyScore = isotropyScore + 200;
                    addExplosion(giantAnomaly.x, giantAnomaly.y, 'unstable');
                    updateUI();
                }
                i--;
            }
        }
        
        // پارتیکل‌ها
        for(let i=0;i<particles.length;i++) {
            particles[i].life -= 0.05;
            if(particles[i].life <= 0) particles.splice(i,1);
        }
        
        // آپدیت رکورد
        if(isotropyScore > highScore) { 
            highScore = isotropyScore; 
            localStorage.setItem('cmbPurifierHigh', highScore); 
            highScoreVal.innerText = highScore; 
        }
        scoreVal.innerText = isotropyScore;
        moneyVal.innerText = cosmicEnergy;
        killCountVal.innerText = anomaliesDestroyed;
    }
    
    function updateHearts() {
        let str = '';
        for(let i=0;i<player.lives;i++) str += '🔴 ';
        for(let i=player.lives;i<player.maxLives+upgrades.extraLives;i++) str += '⚫ ';
        heartsDisplay.innerHTML = str;
    }
    
    function updateUI() {
        scoreVal.innerText = isotropyScore;
        moneyVal.innerText = cosmicEnergy;
        killCountVal.innerText = anomaliesDestroyed;
        if(isotropyScore > highScore) { highScore = isotropyScore; highScoreVal.innerText = highScore; localStorage.setItem('cmbPurifierHigh', highScore); }
        updateHearts();
    }
    
    function draw() {
        ctx.clearRect(0,0,canvas.width,canvas.height);
        
        // پس‌زمینه CMB-like (تابش زمینه)
        const grad = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
        grad.addColorStop(0, '#030018');
        grad.addColorStop(1, '#000008');
        ctx.fillStyle = grad;
        ctx.fillRect(0,0,canvas.width,canvas.height);
        
        // نویز CMB (نقاط ریز تصادفی)
        for(let i=0;i<300;i++) {
            ctx.fillStyle = `rgba(255,200,100,${Math.random()*0.3})`;
            ctx.fillRect(Math.random()*canvas.width, Math.random()*canvas.height, 1.5, 1.5);
        }
        
        // ستاره‌ها
        for(let s of stars) { 
            ctx.fillStyle = `rgba(255,255,200,${0.3+Math.random()*0.5})`; 
            ctx.fillRect(s.x,s.y,s.size,s.size); 
        }
        
        // سفینه تصفیه‌گر CMB
        ctx.shadowBlur = 12;
        ctx.fillStyle = '#00ccaa';
        ctx.beginPath();
        ctx.moveTo(player.x, player.y-20);
        ctx.lineTo(player.x-18, player.y+8);
        ctx.lineTo(player.x-8, player.y+4);
        ctx.lineTo(player.x-8, player.y+14);
        ctx.lineTo(player.x, player.y+10);
        ctx.lineTo(player.x+8, player.y+14);
        ctx.lineTo(player.x+8, player.y+4);
        ctx.lineTo(player.x+18, player.y+8);
        ctx.fill();
        ctx.fillStyle = '#88ffff';
        ctx.beginPath();
        ctx.arc(player.x, player.y-8, 5, 0, Math.PI*2);
        ctx.fill();
        ctx.shadowBlur = 0;
        
        for(let b of purificationBeams) b.draw();
        for(let a of anomalies) a.draw();
        for(let p of particles) { ctx.fillStyle = `rgba(${p.color || '255,100,0'},${p.life})`; ctx.fillRect(p.x,p.y,p.size,p.size); }
        
        // متن آموزشی
        ctx.font = "bold 12px Orbitron";
        ctx.fillStyle = "#88aaff";
        ctx.fillText("🌡️ نقاط داغ و سرد CMB رو تصفیه کن | حرکت با انگشت | خودکار شلیک", 20, 35);
        ctx.fillStyle = "#ffaa66";
        ctx.fillText(`🌌 دمای فعلی CMB: ${(2.725 + isotropyScore/1000).toFixed(3)} K`, canvas.width-180, 30);
    }
    
    let spawnInterval;
    function startGameLoop() {
        if(spawnInterval) clearInterval(spawnInterval);
        spawnInterval = setInterval(() => { if(gameRunning && !giantAnomalyActive) spawnAnomaly(); }, 1100);
        function frame() {
            if(!gameRunning) return;
            updateGame();
            draw();
            requestAnimationFrame(frame);
        }
        frame();
    }
    
    function endGame() {
        gameRunning = false;
        if(spawnInterval) clearInterval(spawnInterval);
        finalStats.innerText = `یکنواختی نهایی: ${isotropyScore}\nناهمسانی‌های تصفیه شده: ${anomaliesDestroyed}\nنوسانات غول‌پیکر: ${Math.floor(isotropyScore/200)}`;
        gameOverModal.classList.remove('hidden');
    }
    
    function restart() {
        gameRunning = true;
        isotropyScore = 0;
        anomaliesDestroyed = 0;
        cosmicEnergy = 0;
        player.lives = 5 + upgrades.extraLives;
        player.maxLives = 5 + upgrades.extraLives;
        anomalies = [];
        purificationBeams = [];
        particles = [];
        giantAnomaly = null;
        giantAnomalyActive = false;
        nextGiantAnomalyScore = 200;
        updateUI();
        gameOverModal.classList.add('hidden');
        if(spawnInterval) clearInterval(spawnInterval);
        spawnInterval = setInterval(() => { if(gameRunning && !giantAnomalyActive) spawnAnomaly(); }, 1100);
    }
    
    // آپگریدها
    function upgradeDamage() { if(cosmicEnergy>=upgradeCost.dmg) { cosmicEnergy-=upgradeCost.dmg; upgrades.purificationPower += 0.18; upgradeCost.dmg = Math.floor(upgradeCost.dmg * 1.4); moneyVal.innerText=cosmicEnergy; } }
    function upgradeFireSpeed() { if(cosmicEnergy>=upgradeCost.speed) { cosmicEnergy-=upgradeCost.speed; upgrades.spectrometerSpeed += 0.25; upgradeCost.speed = Math.floor(upgradeCost.speed * 1.4); moneyVal.innerText=cosmicEnergy; } }
    function upgradeLife() { if(cosmicEnergy>=upgradeCost.life) { cosmicEnergy-=upgradeCost.life; upgrades.extraLives++; player.maxLives = 5+upgrades.extraLives; player.lives = player.maxLives; upgradeCost.life = Math.floor(upgradeCost.life * 1.5); updateHearts(); moneyVal.innerText=cosmicEnergy; } }
    function upgradeCrit() { if(cosmicEnergy>=upgradeCost.crit) { cosmicEnergy-=upgradeCost.crit; upgrades.critChance = Math.min(0.55, upgrades.critChance+0.08); upgradeCost.crit = Math.floor(upgradeCost.crit * 1.4); moneyVal.innerText=cosmicEnergy; } }
    
    document.getElementById('upgradeDmg').onclick = upgradeDamage;
    document.getElementById('upgradeSpeed').onclick = upgradeFireSpeed;
    document.getElementById('upgradeLife').onclick = upgradeLife;
    document.getElementById('upgradeCrit').onclick = upgradeCrit;
    
    canvas.addEventListener('mousemove', movePlayer);
    canvas.addEventListener('touchmove', movePlayer);
    canvas.addEventListener('click', () => shoot());
    canvas.addEventListener('touchstart', (e) => { e.preventDefault(); shoot(); });
    restartBtn.onclick = () => restart();
    playAgainModalBtn.onclick = () => restart();
    toggleUpgradeBtn.onclick = () => upgradePanel.classList.toggle('hidden');
    
    setInterval(() => { if(gameRunning) shoot(); }, 100);
    startGameLoop();
    updateHearts();
</script>
</body>
</html>

Game Source: 🌌 CMB PURIFIER - پالایشگر تابش زمینه کیهانی

Creator: RapidKnight54

Libraries: none

Complexity: complex (718 lines, 27.6 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: cmb-purifier-rapidknight54" to link back to the original. Then publish at arcadelab.ai/publish.