🎮ArcadeLab

CMB DEFENDER - مدافع تابش زمینه کیهانی

by ElectricCobra60
539 lines17.7 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 DEFENDER - مدافع تابش زمینه کیهانی</title>
    <style>
        * {
            user-select: none;
            touch-action: manipulation;
            box-sizing: border-box;
        }

        body {
            margin: 0;
            min-height: 100vh;
            background: radial-gradient(ellipse at 20% 30%, #010018 0%, #000000 100%);
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Orbitron', 'Courier New', monospace;
            padding: 15px;
        }

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

        .game-container {
            max-width: 600px;
            width: 100%;
            position: relative;
        }

        canvas {
            display: block;
            width: 100%;
            height: auto;
            background: #030014;
            border-radius: 40px;
            box-shadow: 0 0 30px rgba(0, 255, 255, 0.4), 0 0 15px rgba(255, 0, 255, 0.2);
            cursor: crosshair;
            touch-action: none;
        }

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

        .stat {
            text-align: center;
            background: rgba(0,0,0,0.5);
            padding: 5px 15px;
            border-radius: 40px;
        }

        .stat span {
            font-size: 0.7rem;
            color: #88aaff;
            letter-spacing: 1px;
        }

        .stat div {
            font-size: 1.7rem;
            font-weight: 900;
            color: #ffd966;
            text-shadow: 0 0 5px orange;
        }

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

        button {
            background: linear-gradient(45deg, #ff416c, #ff4b2b);
            border: none;
            padding: 12px 20px;
            border-radius: 40px;
            font-family: 'Orbitron', monospace;
            font-weight: bold;
            font-size: 0.9rem;
            color: white;
            cursor: pointer;
            transition: 0.2s;
            box-shadow: 0 0 12px #ff416c;
        }

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

        .controls {
            margin-top: 15px;
            display: flex;
            gap: 10px;
            justify-content: center;
        }

        .powerup-indicator {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: gold;
            color: black;
            padding: 8px 16px;
            border-radius: 40px;
            font-weight: bold;
            animation: fadeOut 1s ease-out forwards;
            pointer-events: none;
            z-index: 100;
            white-space: nowrap;
        }

        @keyframes fadeOut {
            0% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
            100% { opacity: 0; transform: translate(-50%, -80%) scale(1.2); }
        }

        .game-over-panel {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(0,0,0,0.95);
            padding: 25px;
            border-radius: 40px;
            text-align: center;
            border: 2px solid cyan;
            backdrop-filter: blur(10px);
            z-index: 200;
            min-width: 250px;
        }

        .hidden {
            display: none;
        }
    </style>
</head>
<body>
<div class="game-container">
    <div class="hud">
        <div class="stat">
            <span>🔥 امتیاز</span>
            <div id="scoreDisplay">0</div>
        </div>
        <div class="stat">
            <span>🏆 رکورد</span>
            <div id="highScoreDisplay">0</div>
        </div>
        <div class="hearts" id="heartsContainer">
            ❤️ ❤️ ❤️
        </div>
        <div class="stat">
            <span>⚡ سطح</span>
            <div id="levelDisplay">1</div>
        </div>
    </div>

    <canvas id="gameCanvas" width="550" height="550"></canvas>

    <div class="controls">
        <button id="restartBtn">🌌 بازی جدید</button>
        <button id="powerSlowBtn" style="background: linear-gradient(45deg, #3a7bd5, #00d2ff);">⏪ کند کردن (1)</button>
    </div>
    <div id="gameOverPanel" class="game-over-panel hidden">
        <h2>💀 GAME OVER 💀</h2>
        <p id="finalScoreMsg">امتیاز شما: 0</p>
        <button id="playAgainBtn">باز هم؟ 🔥</button>
    </div>
</div>

<script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    
    let animationId;
    let gameActive = true;
    
    // تنظیم سایز
    function resizeCanvas() {
        const size = Math.min(window.innerWidth - 40, 550);
        canvas.style.width = `${size}px`;
        canvas.style.height = `${size}px`;
        canvas.width = 550;
        canvas.height = 550;
    }
    window.addEventListener('resize', resizeCanvas);
    resizeCanvas();

    // عناصر بازی
    let enemies = [];
    let powerups = [];
    let score = 0;
    let lives = 3;
    let level = 1;
    let highScore = localStorage.getItem('cmbHighScore') ? parseInt(localStorage.getItem('cmbHighScore')) : 0;
    let slowMotion = false;
    let slowTimer = null;
    let powerSlowCount = 1;
    
    // متغیرهای سختی
    let baseSpawnDelay = 1200;
    let lastSpawn = 0;
    
    // المان‌ها
    const scoreDisplay = document.getElementById('scoreDisplay');
    const highScoreDisplay = document.getElementById('highScoreDisplay');
    const heartsContainer = document.getElementById('heartsContainer');
    const levelDisplay = document.getElementById('levelDisplay');
    const restartBtn = document.getElementById('restartBtn');
    const powerSlowBtn = document.getElementById('powerSlowBtn');
    const gameOverPanel = document.getElementById('gameOverPanel');
    const playAgainBtn = document.getElementById('playAgainBtn');
    const finalScoreMsg = document.getElementById('finalScoreMsg');
    
    highScoreDisplay.innerText = highScore;
    
    // آپدیت قلب‌ها
    function updateHearts() {
        let heartsHtml = '';
        for(let i = 0; i < lives; i++) heartsHtml += '❤️ ';
        for(let i = lives; i < 3; i++) heartsHtml += '🖤 ';
        heartsContainer.innerHTML = heartsHtml;
    }
    
    // کلاس دشمن
    class Enemy {
        constructor(x, y, type) {
            this.x = x;
            this.y = y;
            this.type = type; // 'hot' or 'cold'
            this.radius = 28;
            this.speedX = (Math.random() - 0.5) * 1.2;
            this.speedY = (Math.random() - 0.5) * 1.2;
        }
        
        update() {
            let speedFactor = slowMotion ? 0.4 : 1;
            this.x += this.speedX * speedFactor;
            this.y += this.speedY * speedFactor;
            // مرزها
            if(this.x - this.radius < 0) { this.x = this.radius; this.speedX *= -1; }
            if(this.x + this.radius > canvas.width) { this.x = canvas.width - this.radius; this.speedX *= -1; }
            if(this.y - this.radius < 0) { this.y = this.radius; this.speedY *= -1; }
            if(this.y + this.radius > canvas.height) { this.y = canvas.height - this.radius; this.speedY *= -1; }
        }
        
        draw() {
            const pulse = 0.85 + Math.sin(Date.now() * 0.008) * 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, '#ffaa44');
                gradient.addColorStop(1, '#dd2200');
            } else {
                gradient.addColorStop(0, '#44ccff');
                gradient.addColorStop(1, '#1155aa');
            }
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.radius * pulse, 0, Math.PI*2);
            ctx.fillStyle = gradient;
            ctx.fill();
            ctx.shadowBlur = 12;
            ctx.shadowColor = this.type === 'hot' ? '#ff6600' : '#00aaff';
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.radius*0.6, 0, Math.PI*2);
            ctx.fillStyle = this.type === 'hot' ? '#ffdd99' : '#aaeeff';
            ctx.fill();
            ctx.shadowBlur = 0;
            ctx.font = "bold 20px monospace";
            ctx.fillStyle = "white";
            ctx.fillText(this.type === 'hot' ? '🌋' : '❄️', this.x-12, this.y+9);
        }
        
        isClicked(clickX, clickY) {
            return Math.hypot(clickX - this.x, clickY - this.y) < this.radius;
        }
    }
    
    // آیتم پاورآپ (قلب یا ستاره)
    class PowerUp {
        constructor(x, y) {
            this.x = x;
            this.y = y;
            this.radius = 18;
            this.type = Math.random() > 0.6 ? 'heart' : 'star';
        }
        
        draw() {
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);
            ctx.fillStyle = this.type === 'heart' ? '#ff3366' : '#ffdd44';
            ctx.fill();
            ctx.fillStyle = 'white';
            ctx.font = "22px monospace";
            ctx.fillText(this.type === 'heart' ? '❤️' : '⭐', this.x-12, this.y+9);
        }
        
        isClicked(clickX, clickY) {
            return Math.hypot(clickX - this.x, clickY - this.y) < this.radius;
        }
    }
    
    function spawnEnemy() {
        if(!gameActive) return;
        const type = Math.random() > 0.5 ? 'hot' : 'cold';
        let x, y;
        if(Math.random() > 0.5) {
            x = Math.random() * canvas.width;
            y = Math.random() > 0.5 ? -30 : canvas.height + 30;
        } else {
            x = Math.random() > 0.5 ? -30 : canvas.width + 30;
            y = Math.random() * canvas.height;
        }
        x = Math.min(Math.max(x, 30), canvas.width - 30);
        y = Math.min(Math.max(y, 30), canvas.height - 30);
        enemies.push(new Enemy(x, y, type));
    }
    
    function spawnPowerUp() {
        if(!gameActive) return;
        if(Math.random() > 0.08) return; // 8% شانس هر فریم نریزیم, ولی هر 2 ثانیه
        let x = 40 + Math.random() * (canvas.width - 80);
        let y = 40 + Math.random() * (canvas.height - 80);
        powerups.push(new PowerUp(x, y));
    }
    
    function drawBackground() {
        const grad = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
        grad.addColorStop(0, '#03001c');
        grad.addColorStop(1, '#000000');
        ctx.fillStyle = grad;
        ctx.fillRect(0,0,canvas.width,canvas.height);
        for(let i=0;i<150;i++) {
            ctx.fillStyle = `rgba(255,255,200,${Math.random()*0.4})`;
            ctx.fillRect(Math.random()*canvas.width, Math.random()*canvas.height, 2,2);
        }
    }
    
    function gameLoop() {
        if(!gameActive) return;
        
        drawBackground();
        
        // اسپاون دشمن (با توجه به سطح)
        let currentDelay = Math.max(500, baseSpawnDelay - Math.floor(level/2) * 50);
        if(Date.now() - lastSpawn > currentDelay) {
            spawnEnemy();
            lastSpawn = Date.now();
            if(level > 2 && Math.random() < 0.3) spawnEnemy(); // دوتایی
        }
        
        spawnPowerUp();
        
        // آپدیت و رندر دشمنان
        for(let i=0; i<enemies.length; i++) {
            enemies[i].update();
            enemies[i].draw();
        }
        
        // پاورآپ‌ها
        for(let p of powerups) p.draw();
        
        // متن سطح و هشدار
        ctx.font = "bold 18px Orbitron";
        ctx.fillStyle = "#88aaff";
        ctx.fillText(`Wave ${level}`, canvas.width-100, 40);
        if(slowMotion) {
            ctx.fillStyle = "cyan";
            ctx.font = "bold 22px Orbitron";
            ctx.fillText("⏪ SLOW TIME", canvas.width/2-80, 70);
        }
        
        animationId = requestAnimationFrame(gameLoop);
    }
    
    // کلیک و شلیک
    function handleShoot(e) {
        if(!gameActive) return;
        e.preventDefault();
        
        const rect = canvas.getBoundingClientRect();
        const scaleX = canvas.width / rect.width;
        const scaleY = canvas.height / rect.height;
        let clientX, clientY;
        if(e.touches) {
            clientX = e.touches[0].clientX;
            clientY = e.touches[0].clientY;
        } else {
            clientX = e.clientX;
            clientY = e.clientY;
        }
        const canvasX = (clientX - rect.left) * scaleX;
        const canvasY = (clientY - rect.top) * scaleY;
        
        // برخورد با دشمن
        let hit = false;
        for(let i=0; i<enemies.length; i++) {
            if(enemies[i].isClicked(canvasX, canvasY)) {
                enemies.splice(i,1);
                score += 10 + Math.floor(level/2);
                scoreDisplay.innerText = score;
                hit = true;
                
                // افزایش سطح هر 100 امتیاز
                let newLevel = 1 + Math.floor(score / 100);
                if(newLevel > level) {
                    level = newLevel;
                    levelDisplay.innerText = level;
                }
                
                if(score > highScore) {
                    highScore = score;
                    highScoreDisplay.innerText = highScore;
                    localStorage.setItem('cmbHighScore', highScore);
                }
                break;
            }
        }
        if(hit) {
            if(navigator.vibrate) navigator.vibrate(30);
            showFloatingText(clientX, clientY, "+"+ (10 + Math.floor(level/2)), "#ffaa44");
            return;
        }
        
        // برخورد با پاورآپ
        for(let i=0; i<powerups.length; i++) {
            if(powerups[i].isClicked(canvasX, canvasY)) {
                if(powerups[i].type === 'heart') {
                    if(lives < 3) lives++;
                    updateHearts();
                    showFloatingText(clientX, clientY, "❤️ +1 Life", "#ff6699");
                } else if(powerups[i].type === 'star') {
                    powerSlowCount++;
                    powerSlowBtn.innerText = `⏪ کند کردن (${powerSlowCount})`;
                    showFloatingText(clientX, clientY, "⭐ Power +1", "#ffdd66");
                }
                powerups.splice(i,1);
                break;
            }
        }
    }
    
    // نمایش متن شناور
    function showFloatingText(x, y, text, color) {
        const div = document.createElement('div');
        div.className = 'powerup-indicator';
        div.innerText = text;
        div.style.color = color;
        div.style.left = x + 'px';
        div.style.top = y + 'px';
        div.style.position = 'fixed';
        document.body.appendChild(div);
        setTimeout(() => div.remove(), 600);
    }
    
    // ضرر خوردن (هر 5 ثانیه یکبار در صورت عدم شلیک یا خطا)
    let lastDamageTime = 0;
    function applyDamage() {
        if(!gameActive) return;
        if(Date.now() - lastDamageTime > 3000 && enemies.length > 5) {
            lives--;
            updateHearts();
            lastDamageTime = Date.now();
            showFloatingText(canvas.width/2, 100, "💔 LOST LIFE", "red");
            if(lives <= 0) endGame();
        }
    }
    
    function endGame() {
        gameActive = false;
        if(animationId) cancelAnimationFrame(animationId);
        finalScoreMsg.innerText = `امتیاز شما: ${score}\nسطح: ${level}`;
        gameOverPanel.classList.remove('hidden');
    }
    
    function restartGame() {
        gameActive = true;
        enemies = [];
        powerups = [];
        score = 0;
        lives = 3;
        level = 1;
        slowMotion = false;
        powerSlowCount = 1;
        if(slowTimer) clearTimeout(slowTimer);
        scoreDisplay.innerText = "0";
        levelDisplay.innerText = "1";
        updateHearts();
        powerSlowBtn.innerText = `⏪ کند کردن (${powerSlowCount})`;
        lastSpawn = Date.now();
        lastDamageTime = Date.now();
        gameOverPanel.classList.add('hidden');
        
        // شروع مجدد لوپ
        if(animationId) cancelAnimationFrame(animationId);
        animationId = requestAnimationFrame(gameLoop);
    }
    
    // قابلیت کند کردن زمان
    function activateSlowMotion() {
        if(!gameActive) return;
        if(powerSlowCount <= 0) {
            showFloatingText(canvas.width/2, 200, "❌ پاور کافی نیست!", "red");
            return;
        }
        powerSlowCount--;
        powerSlowBtn.innerText = `⏪ کند کردن (${powerSlowCount})`;
        slowMotion = true;
        if(slowTimer) clearTimeout(slowTimer);
        slowTimer = setTimeout(() => { slowMotion = false; }, 4000);
        showFloatingText(canvas.width/2, 150, "🐢 SLOW TIME 4s", "cyan");
    }
    
    // رویدادها
    canvas.addEventListener('click', handleShoot);
    canvas.addEventListener('touchstart', handleShoot, { passive: false });
    restartBtn.addEventListener('click', () => restartGame());
    playAgainBtn.addEventListener('click', () => restartGame());
    powerSlowBtn.addEventListener('click', () => activateSlowMotion());
    
    // حلقه آسیب
    setInterval(() => applyDamage(), 2000);
    
    // شروع بازی
    restartGame();
</script>
</body>
</html>

Game Source: CMB DEFENDER - مدافع تابش زمینه کیهانی

Creator: ElectricCobra60

Libraries: none

Complexity: complex (539 lines, 17.7 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-defender-electriccobra60" to link back to the original. Then publish at arcadelab.ai/publish.