HTML跑酷
先看效果
再上代码
<!DOCTYPE html>
<html>
<head>
<title>火柴人跑酷</title>
<style>
body {
margin: 0;
overflow: hidden;
background: #87CEEB;
}
#gameCanvas {
background: linear-gradient(to bottom, #87CEEB 0%, #87CEEB 50%, #228B22 50%, #228B22 100%);
}
#ui {
position: fixed;
top: 20px;
left: 20px;
font-family: Arial;
font-size: 24px;
color: white;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
#gameOver {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0,0,0,0.8);
color: white;
padding: 20px;
text-align: center;
border-radius: 10px;
}
</style>
</head>
<body>
<div id="ui">
得分: <span id="score">0</span>
</div>
<div id="gameOver">
<h2>游戏结束!</h2>
<p>最终得分: <span id="finalScore">0</span></p>
<button onclick="restartGame()">重玩</button>
</div>
<canvas id="gameCanvas"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
let canvasWidth = window.innerWidth;
let canvasHeight = window.innerHeight;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
// 游戏参数
let gameSpeed = 10;
let isJumping = false;
let isGameOver = false;
let score = 0;
let gravity = 0.8;
let jumpForce = -21;
let groundLevel = canvasHeight * 0.8;
// 火柴人参数
let stickman = {
x: 100,
y: groundLevel - 60,
width: 40,
height: 80,
velocityY: 0,
isOnGround: true
};
// 障碍物数组
let obstacles = [];
let obstacleTypes = [
{ width: 30, height: 50 },
{ width: 50, height: 30 },
{ width: 40, height: 40 }
];
// 游戏循环
function gameLoop() {
if (!isGameOver) {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
updateStickman();
updateObstacles();
checkCollisions();
drawGround();
drawStickman();
drawObstacles();
updateScore();
requestAnimationFrame(gameLoop);
}
}
function drawStickman() {
// 绘制火柴人
ctx.fillStyle = '#000';
// 身体
ctx.beginPath();
ctx.moveTo(stickman.x + stickman.width/2, stickman.y);
ctx.lineTo(stickman.x + stickman.width/2, stickman.y + stickman.height);
ctx.stroke();
// 头部
ctx.beginPath();
ctx.arc(stickman.x + stickman.width/2, stickman.y - 10, 15, 0, Math.PI * 2);
ctx.stroke();
// 腿
ctx.beginPath();
ctx.moveTo(stickman.x + stickman.width/2, stickman.y + stickman.height);
ctx.lineTo(stickman.x, stickman.y + stickman.height + 30);
ctx.moveTo(stickman.x + stickman.width/2, stickman.y + stickman.height);
ctx.lineTo(stickman.x + stickman.width, stickman.y + stickman.height + 30);
ctx.stroke();
}
function updateStickman() {
// 重力应用
if (!stickman.isOnGround) {
stickman.velocityY += gravity;
stickman.y += stickman.velocityY;
}
// 地面检测
if (stickman.y + stickman.height > groundLevel) {
stickman.y = groundLevel - stickman.height;
stickman.velocityY = 0;
stickman.isOnGround = true;
}
}
function drawGround() {
ctx.fillStyle = '#228B22';
ctx.fillRect(0, groundLevel, canvasWidth, canvasHeight - groundLevel);
}
function generateObstacle() {
if (Math.random() < 0.02) {
let type = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];
obstacles.push({
x: canvasWidth,
y: groundLevel - type.height,
width: type.width,
height: type.height,
passed: false
});
}
}
function updateObstacles() {
generateObstacle();
for (let i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].x -= gameSpeed;
if (obstacles[i].x + obstacles[i].width < 0) {
obstacles.splice(i, 1);
}
}
}
function drawObstacles() {
ctx.fillStyle = '#8B4513';
obstacles.forEach(obstacle => {
ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);
});
}
function checkCollisions() {
obstacles.forEach(obstacle => {
if (
stickman.x < obstacle.x + obstacle.width &&
stickman.x + stickman.width > obstacle.x &&
stickman.y < obstacle.y + obstacle.height &&
stickman.y + stickman.height > obstacle.y
) {
gameOver();
}
if (!obstacle.passed && obstacle.x + obstacle.width < stickman.x) {
obstacle.passed = true;
score += 10;
}
});
}
function updateScore() {
document.getElementById('score').textContent = score;
gameSpeed += 0.001;
}
function gameOver() {
isGameOver = true;
document.getElementById('gameOver').style.display = 'block';
document.getElementById('finalScore').textContent = score;
}
function restartGame() {
isGameOver = false;
score = 0;
gameSpeed = 10;
obstacles = [];
stickman.y = groundLevel - 60;
stickman.velocityY = 0;
document.getElementById('gameOver').style.display = 'none';
gameLoop();
}
// 事件监听
document.addEventListener('keydown', (e) => {
if ((e.code === 'Space' || e.code === 'ArrowUp') && stickman.isOnGround) {
stickman.velocityY = jumpForce;
stickman.isOnGround = false;
}
});
// 窗口调整
window.addEventListener('resize', () => {
canvasWidth = window.innerWidth;
canvasHeight = window.innerHeight;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
groundLevel = canvasHeight * 0.8;
});
// 启动游戏
gameLoop();
</script>
</body>
</html>