Meta Description" name="description" />
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Neon City Runner</title>
<style>
body {
margin: 0;
background: #05010a;
overflow: hidden;
font-family: Arial, sans-serif;
color: white;
}
canvas {
display: block;
margin: auto;
background: linear-gradient(to top, #0a0020, #12004a);
}
#ui {
position: fixed;
top: 10px;
left: 10px;
font-size: 18px;
}
</style>
</head>
<body>
<div id="ui">
Điểm: <span id="score">0</span><br>
Skin: <span id="skin">1</span>
</div>
<canvas id="game" width="900" height="500"></canvas>
<script>
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
let score = 0;
let gameOver = false;
const skins = ["#00ffff", "#ff00ff", "#00ff66", "#ffcc00"];
let currentSkin = 0;
const player = {
x: 100,
y: 380,
w: 40,
h: 60,
vy: 0,
jump: false
};
let obstacles = [];
let orbs = [];
let frame = 0;
// Điều khiển
document.addEventListener("keydown", e => {
if (e.key === "ArrowUp" && !player.jump) {
player.vy = -15;
player.jump = true;
}
if (e.key === "ArrowLeft") player.x -= 20;
if (e.key === "ArrowRight") player.x += 20;
if (e.key.toLowerCase() === "s") {
currentSkin = (currentSkin + 1) % skins.length;
document.getElementById("skin").innerText = currentSkin + 1;
}
});
// Vẽ thành phố
function drawCity() {
for (let i = 0; i < 30; i++) {
const x = (i * 80 - frame) % canvas.width;
const h = Math.random() * 200 + 100;
ctx.fillStyle = "rgba(0,255,255,0.15)";
ctx.fillRect(x, canvas.height - h, 60, h);
}
}
// Game loop
function update() {
if (gameOver) return;
frame++;
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawCity();
// Player
player.vy += 0.8;
player.y += player.vy;
if (player.y >= 380) {
player.y = 380;
player.jump = false;
}
ctx.fillStyle = skins[currentSkin];
ctx.fillRect(player.x, player.y, player.w, player.h);
// Spawn obstacle
if (frame % 90 === 0) {
obstacles.push({ x: canvas.width, y: 400, w: 30, h: 40 });
}
// Spawn orb
if (frame % 120 === 0) {
orbs.push({ x: canvas.width, y: 320 });
}
// Obstacles
obstacles.forEach((o, i) => {
o.x -= 6;
ctx.fillStyle = "#ff0033";
ctx.fillRect(o.x, o.y, o.w, o.h);
if (
player.x < o.x + o.w &&
player.x + player.w > o.x &&
player.y < o.y + o.h &&
player.y + player.h > o.y
) {
gameOver = true;
alert("GAME OVER! Điểm của bạn: " + score);
location.reload();
}
});
// Orbs
orbs.forEach((o, i) => {
o.x -= 5;
ctx.beginPath();
ctx.arc(o.x, o.y, 8, 0, Math.PI * 2);
ctx.fillStyle = "#00ffcc";
ctx.fill();
if (
Math.abs(player.x - o.x) < 30 &&
Math.abs(player.y - o.y) < 40
) {
score++;
document.getElementById("score").innerText = score;
orbs.splice(i, 1);
}
});
requestAnimationFrame(update);
}
update();
</script>
</body>
</html>
1
1
4KB
4KB
110.0ms
196.0ms
110.0ms