🎮ArcadeLab

SIÊU CHIẾN KIỂM v2

by PlasmaRanger34
299 lines14.7 KB
▶ Play
<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SIÊU CHIẾN KIỂM v2</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', sans-serif; }
        body { background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%); min-height: 100vh; display: flex; flex-direction: column; align-items: center; color: white; overflow: hidden; padding: 10px; }
        
        h1 { margin-top: 10px; font-size: clamp(1.8rem, 5vw, 2.5rem); background: linear-gradient(90deg, #ffd700, #ff6b00); -webkit-background-clip: text; -webkit-text-fill-color: transparent; text-shadow: 0 0 30px rgba(255,107,0,0.3); text-align: center; }
        
        .difficulty-container { margin: 15px 0; display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
        .diff-btn { padding: 10px 20px; border: none; border-radius: 12px; font-size: 1rem; font-weight: bold; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 4px 15px rgba(0,0,0,0.3); }
        .diff-btn:hover { transform: translateY(-2px); }
        .easy { background: linear-gradient(135deg, #4CAF50, #2E7D32); color: white; }
        .normal { background: linear-gradient(135deg, #2196F3, #1565C0); color: white; }
        .hard { background: linear-gradient(135deg, #f44336, #c62828); color: white; }
        .diff-btn.active { box-shadow: 0 0 20px currentColor, inset 0 0 10px rgba(255,255,255,0.3); transform: scale(1.05); }
        
        #gameCanvas { border: 4px solid #ffd700; border-radius: 15px; box-shadow: 0 0 30px rgba(255,215,0,0.4), inset 0 0 50px rgba(0,0,0,0.5); background: linear-gradient(180deg, #87CEEB 0%, #228B22 100%); max-width: 100%; height: auto; }
        
        .ui-container { display: flex; gap: 20px; margin: 10px 0; flex-wrap: wrap; justify-content: center; }
        .player-ui { background: rgba(0,0,0,0.6); padding: 12px 20px; border-radius: 15px; border: 2px solid; min-width: 180px; }
        .p1 { border-color: #4CAF50; }
        .p2 { border-color: #f44336; }
        .health-bar { width: 100%; height: 22px; background: #333; border-radius: 11px; overflow: hidden; margin: 8px 0; }
        .health-fill { height: 100%; border-radius: 11px; transition: width 0.3s ease; }
        .p1 .health-fill { background: linear-gradient(90deg, #4CAF50, #8BC34A); }
        .p2 .health-fill { background: linear-gradient(90deg, #f44336, #ff6b6b); }
        .shield-bar { width: 100%; height: 12px; background: #333; border-radius: 6px; overflow: hidden; margin-top: 5px; }
        .shield-fill { height: 100%; background: linear-gradient(90deg, #2196F3, #03A9F4); border-radius: 6px; transition: width 0.3s ease; }
        .controls { margin-top: 15px; background: rgba(0,0,0,0.5); padding: 12px 20px; border-radius: 12px; font-size: 0.85rem; line-height: 1.6; text-align: center; max-width: 600px; }
        .start-btn { margin-top: 15px; padding: 12px 35px; font-size: 1.2rem; font-weight: bold; background: linear-gradient(135deg, #ffd700, #ff8c00); border: none; border-radius: 12px; cursor: pointer; color: #1a1a2e; box-shadow: 0 0 20px rgba(255,215,0,0.5); transition: all 0.3s ease; }
        .start-btn:hover { transform: scale(1.05); box-shadow: 0 0 30px rgba(255,215,0,0.7); }
        .game-message { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: clamp(2rem, 8vw, 3.5rem); font-weight: bold; color: #ffd700; text-shadow: 0 0 20px black, 0 0 40px rgba(255,215,0,0.5); pointer-events: none; opacity: 0; transition: opacity 0.5s ease; z-index: 10; text-align: center; }
        .game-message.show { opacity: 1; pointer-events: auto; }
    </style>
</head>
<body>
    <h1>⚔️ SIÊU CHIẾN KIỂM v2 ⚔️</h1>
    
    <div class="difficulty-container">
        <button class="diff-btn easy active" data-diff="easy">🟢 DỄ</button>
        <button class="diff-btn normal" data-diff="normal">🔵 BÌNH THƯỜNG</button>
        <button class="diff-btn hard" data-diff="hard">🔴 KHÓ</button>
    </div>
    
    <div class="ui-container">
        <div class="player-ui p1">
            <h3>🟢 NGƯỜI CHƠI</h3>
            <div>Máu: <span id="p1-hp-text">100</span>/100</div>
            <div class="health-bar"><div class="health-fill" id="p1-hp" style="width:100%"></div></div>
            <div>Khiên: <span id="p1-shield-text">50</span>/50</div>
            <div class="shield-bar"><div class="shield-fill" id="p1-shield" style="width:100%"></div></div>
        </div>
        <div class="player-ui p2">
            <h3>🔴 KẺ THÙ</h3>
            <div>Máu: <span id="p2-hp-text">100</span>/100</div>
            <div class="health-bar"><div class="health-fill" id="p2-hp" style="width:100%"></div></div>
            <div>Khiên: <span id="p2-shield-text">50</span>/50</div>
            <div class="shield-bar"><div class="shield-fill" id="p2-shield" style="width:100%"></div></div>
        </div>
    </div>
    
    <canvas id="gameCanvas" width="900" height="500"></canvas>
    
    <div class="controls">
        <strong>🎮 HƯỚNG DẪN CHƠI:</strong><br>
        ← → ↑ ↓ / WASD = Di chuyển | J = Chém kiếm | K = Đỡ khiên (giữ) | L = Hồi máu
    </div>
    
    <button class="start-btn" id="startBtn">🎮 BẮT ĐẦU CHƠI</button>
    
    <div class="game-message" id="gameMsg"></div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const startBtn = document.getElementById('startBtn');
        const gameMsg = document.getElementById('gameMsg');
        
        let difficulty = 'easy';
        const diffSettings = {
            easy: { enemySpeed: 1.5, enemyDamage: 5, healAmount: 20, shieldRegen: 0.3 },
            normal: { enemySpeed: 2.5, enemyDamage: 8, healAmount: 15, shieldRegen: 0.2 },
            hard: { enemySpeed: 4, enemyDamage: 12, healAmount: 10, shieldRegen: 0.1 }
        };
        
        let gameRunning = false;
        const keys = {};
        
        class Fighter {
            constructor(x, y, color, isPlayer = false) {
                this.x = x; this.y = y; this.width = 50; this.height = 70;
                this.color = color; this.hp = 100; this.maxHp = 100;
                this.shield = 50; this.maxShield = 50;
                this.speed = 4; this.attackCooldown = 0;
                this.attacking = false; this.attackFrame = 0;
                this.blocking = false; this.facingRight = isPlayer;
                this.isPlayer = isPlayer; this.healCooldown = 0;
            }
            
            draw() {
                ctx.fillStyle = this.color;
                ctx.shadowBlur = 15; ctx.shadowColor = this.color;
                ctx.fillRect(this.x - this.width/2, this.y - this.height/2, this.width, this.height);
                ctx.shadowBlur = 0;
                
                ctx.fillStyle = '#ffe4c4';
                ctx.beginPath();
                ctx.arc(this.x, this.y - this.height/2 + 15, 15, 0, Math.PI * 2);
                ctx.fill();
                
                ctx.save();
                ctx.translate(this.x + (this.facingRight ? 25 : -25), this.y);
                if (this.attacking) {
                    ctx.rotate((this.facingRight ? 1 : -1) * Math.PI/4 * Math.sin(this.attackFrame * 0.5));
                }
                ctx.fillStyle = '#c0c0c0';
                ctx.fillRect(-3, -40, 6, 40);
                ctx.fillStyle = '#ffd700';
                ctx.fillRect(-8, 0, 16, 8);
                ctx.restore();
                
                if (this.blocking) {
                    ctx.fillStyle = 'rgba(33, 150, 243, 0.7)';
                    ctx.beginPath();
                    ctx.arc(this.x + (this.facingRight ? 30 : -30), this.y, 25, 0, Math.PI * 2);
                    ctx.fill();
                    ctx.strokeStyle = '#fff'; ctx.lineWidth = 3; ctx.stroke();
                }
                
                if (this.healCooldown > 80) {
                    ctx.fillStyle = '#4CAF50';
                    ctx.font = 'bold 20px Arial';
                    ctx.fillText('+♥', this.x - 15, this.y - 50 + (100 - this.healCooldown));
                }
            }
            
            move(dx, dy) {
                this.x = Math.max(30, Math.min(canvas.width - 30, this.x + dx * this.speed));
                this.y = Math.max(50, Math.min(canvas.height - 30, this.y + dy * this.speed));
                if (dx > 0) this.facingRight = true;
                if (dx < 0) this.facingRight = false;
            }
            
            attack(enemy) {
                if (this.attackCooldown > 0) return;
                this.attacking = true;
                this.attackFrame = 0;
                this.attackCooldown = 25;
                
                const attackRange = 70;
                const dist = Math.hypot(this.x - enemy.x, this.y - enemy.y);
                const correctDir = (this.facingRight && this.x < enemy.x) || (!this.facingRight && this.x > enemy.x);
                
                if (dist < attackRange && correctDir) {
                    let dmg = 15;
                    if (enemy.blocking) {
                        const absorbed = Math.min(enemy.shield, dmg);
                        enemy.shield -= absorbed;
                        dmg -= absorbed;
                    }
                    enemy.hp = Math.max(0, enemy.hp - dmg);
                }
            }
            
            heal() {
                if (this.healCooldown > 0) return;
                this.healCooldown = 100;
                const amount = diffSettings[difficulty].healAmount;
                this.hp = Math.min(this.maxHp, this.hp + amount);
            }
            
            update(enemy) {
                if (this.attackCooldown > 0) this.attackCooldown--;
                if (this.healCooldown > 0) this.healCooldown--;
                if (this.attacking) {
                    this.attackFrame++;
                    if (this.attackFrame > 10) this.attacking = false;
                }
                if (!this.blocking && this.shield < this.maxShield) {
                    this.shield = Math.min(this.maxShield, this.shield + diffSettings[difficulty].shieldRegen);
                }
            }
        }
        
        const player = new Fighter(150, 250, '#4CAF50', true);
        const enemy = new Fighter(750, 250, '#f44336', false);
        
        document.querySelectorAll('.diff-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                document.querySelectorAll('.diff-btn').forEach(b => b.classList.remove('active'));
                btn.classList.add('active');
                difficulty = btn.dataset.diff;
            });
        });
        
        startBtn.addEventListener('click', () => {
            player.x = 150; player.y = 250; player.hp = 100; player.shield = 50;
            enemy.x = 750; enemy.y = 250; enemy.hp = 100; enemy.shield = 50;
            gameRunning = true;
            startBtn.style.display = 'none';
            gameMsg.classList.remove('show');
            updateUI();
        });
        
        document.addEventListener('keydown', e => {
            keys[e.key.toLowerCase()] = true;
            if (!gameRunning) return;
            if (e.key.toLowerCase() === 'j') player.attack(enemy);
            if (e.key.toLowerCase() === 'k') player.blocking = true;
            if (e.key.toLowerCase() === 'l') player.heal();
        });
        document.addEventListener('keyup', e => {
            keys[e.key.toLowerCase()] = false;
            if (e.key.toLowerCase() === 'k') player.blocking = false;
        });
        
        function updateUI() {
            document.getElementById('p1-hp').style.width = `${player.hp}%`;
            document.getElementById('p1-hp-text').textContent = Math.round(player.hp);
            document.getElementById('p1-shield').style.width = `${(player.shield / player.maxShield) * 100}%`;
            document.getElementById('p1-shield-text').textContent = Math.round(player.shield);
            
            document.getElementById('p2-hp').style.width = `${enemy.hp}%`;
            document.getElementById('p2-hp-text').textContent = Math.round(enemy.hp);
            document.getElementById('p2-shield').style.width = `${(enemy.shield / enemy.maxShield) * 100}%`;
            document.getElementById('p2-shield-text').textContent = Math.round(enemy.shield);
        }
        
        function endGame(winner) {
            gameRunning = false;
            gameMsg.textContent = winner === 'player' ? '🏆 BẠN THẮNG! 🏆' : '💀 BẠN THUA! 💀';
            gameMsg.classList.add('show');
            startBtn.style.display = 'block';
            startBtn.textContent = '🔄 CHƠI LẠI';
        }
        
        function gameLoop() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            const grad = ctx.createLinearGradient(0, 0, 0, canvas.height);
            grad.addColorStop(0, '#87CEEB');
            grad.addColorStop(0.7, '#228B22');
            ctx.fillStyle = grad;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            ctx.strokeStyle = 'rgba(255,255,255,0.3)';
            ctx.lineWidth = 3;
            ctx.setLineDash([15, 10]);
            ctx.beginPath();
            ctx.moveTo(canvas.width/2, 0);
            ctx.lineTo(canvas.width/2, canvas.height);
            ctx.stroke();
            ctx.setLineDash([]);
            
            if (gameRunning) {
                let dx = 0, dy = 0;
                if (keys['arrowleft'] || keys['a']) dx = -1;
                if (keys['arrowright'] || keys['d']) dx = 1;
                if (keys['arrowup'] || keys['w']) dy = -1;
                if (keys['arrowdown'] || keys['s']) dy = 1;
                if (!player.blocking) player.move(dx, dy);
                
                const settings = diffSettings[difficulty];
                const dxEnemy = player.x - enemy.x;
                const dyEnemy = player.y - enemy.y;
                const dist = Math.hypot(dxEnemy, dyEnemy);
                enemy.facingRight = dxEnemy > 0;
                
                if (!enemy.blocking) {
                    if (dist > 60) {
                        enemy.move(Math.sign(dxEnemy) * settings.enemySpeed, Math.sign(dyEnemy) * settings.enemySpeed * 0.5);
                    } else {
                        enemy.attack(player);
                    }
                }
                
                player.update(enemy);
                enemy.update(player);
                
                if (player.hp <= 0) endGame('enemy');
                if (enemy.hp <= 0) endGame('player');
            }
            
            player.draw();
            enemy.draw();
            
            if (gameRunning) updateUI();
            
            requestAnimationFrame(gameLoop);
        }
        
        gameLoop();
    </script>
</body>
</html>

Game Source: SIÊU CHIẾN KIỂM v2

Creator: PlasmaRanger34

Libraries: none

Complexity: complex (299 lines, 14.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: si-u-chi-n-ki-m-v2-plasmaranger34" to link back to the original. Then publish at arcadelab.ai/publish.