SIÊU CHIẾN KIỂM v2
by PlasmaRanger34299 lines14.7 KB
<!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.