哈喽大家好,这里是大白百宝阁,每天分享一段小代码~
今天要分享的是,不到200行代码,制作html版贪吃蛇,效果如下:
游戏结束后,还会显示:
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>贪吃蛇游戏</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #333;
}
canvas {
border: 1px solid #fff;
}
</style>
</head>
<body>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// 常量
const GRID_SIZE = 20;
const CELL_SIZE = canvas.width / GRID_SIZE;
// 蛇的初始化
let snake = [
{ x: 5, y: 10 },
{ x: 4, y: 10 },
{ x: 3, y: 10 }
];
// 食物的初始化
let food = {
x: Math.floor(Math.random() * GRID_SIZE),
y: Math.floor(Math.random() * GRID_SIZE)
};
let direction = 'right';
let score = 0;
let gameInterval;
let gameSpeed = 300;
// 移动蛇
function moveSnake() {
const head = { x: snake[0].x, y: snake[0].y };
switch (direction) {
case 'up':
head.y--;
break;
case 'down':
head.y++;
break;
case 'left':
head.x--;
break;
case 'right':
head.x++;
break;
}
// 检查是否吃到食物
if (head.x === food.x && head.y === food.y) {
score++;
generateFood();
increaseGameSpeed();
} else {
snake.pop();
}
snake.unshift(head);
// 检查是否撞到墙壁或自己
if (head.x < 0 || head.x >= GRID_SIZE || head.y < 0 || head.y >= GRID_SIZE || checkCollision(head)) {
stopGame();
alert(`游戏结束! 你的得分是 ${score}`);
resetGame();
}
}
// 检查蛇头是否撞到自己
function checkCollision(head) {
for (let i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) {
return true;
}
}
return false;
}
// 绘制蛇
function drawSnake() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawGrid();
ctx.fillStyle = '#fff';
snake.forEach(segment => {
ctx.fillRect(segment.x * CELL_SIZE, segment.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
});
}
// 绘制食物
function drawFood() {
ctx.fillStyle = '#f00';
ctx.fillRect(food.x * CELL_SIZE, food.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
// 绘制网格
function drawGrid() {
ctx.strokeStyle = '#444';
for (let x = 0; x <= canvas.width; x += CELL_SIZE) {
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, canvas.height);
ctx.stroke();
}
for (let y = 0; y <= canvas.height; y += CELL_SIZE) {
ctx.beginPath();
ctx.moveTo(0, y);
ctx.lineTo(canvas.width, y);
ctx.stroke();
}
}
// 生成新的食物
function generateFood() {
food = {
x: Math.floor(Math.random() * GRID_SIZE),
y: Math.floor(Math.random() * GRID_SIZE)
};
}
// 增加游戏速度
function increaseGameSpeed() {
gameSpeed = Math.max(gameSpeed - 20, 100);
stopGame();
startGame();
}
// 重置游戏
function resetGame() {
snake = [
{ x: 5, y: 10 },
{ x: 4, y: 10 },
{ x: 3, y: 10 }
];
direction = 'right';
score = 0;
gameSpeed = 300;
generateFood();
startGame();
}
// 开始游戏
function startGame() {
gameInterval = setInterval(function() {
moveSnake();
drawSnake();
drawFood();
}, gameSpeed);
}
// 停止游戏
function stopGame() {
clearInterval(gameInterval);
}
// 监听键盘事件改变蛇的移动方向
document.addEventListener('keydown', (event) => {
switch (event.key) {
case 'ArrowUp':
if (direction !== 'down') direction = 'up';
break;
case 'ArrowDown':
if (direction !== 'up') direction = 'down';
break;
case 'ArrowLeft':
if (direction !== 'right') direction = 'left';
break;
case 'ArrowRight':
if (direction !== 'left') direction = 'right';
break;
}
});
// 开始游戏
resetGame();
</script>
</body>
</html>
大白会在下一篇文章中,详细解释该代码的运作,并且给出优化UI和性能的方案,关注我,我们在下一篇文章见~