使用 Canvas 实现贪吃蛇小游戏
在这篇博客中,我们将介绍如何使用 HTML5 Canvas 和 JavaScript 实现一个简单的贪吃蛇(Snake)小游戏。这个项目是一个基础的游戏开发练习,它可以帮助你理解如何在 Canvas 上绘图、如何处理用户输入以及如何管理游戏状态。
项目结构
在开始之前,确保你的项目文件结构如下:
index.html
index.css
index.js
HTML 部分
首先,我们在 index.html
中定义 Canvas 和一个重新开始按钮。
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>贪吃蛇游戏</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<button id="restartButton" style="display: none;" onclick="restartGame()">重新开始</button>
<script src="index.js"></script>
</body>
</html>
CSS 部分
在 index.css
中,我们可以设置 Canvas 和按钮的样式。
/* styles.css */
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
canvas {
border: 1px solid #000;
background-color: #fff;
}
button {
display: none;
margin-top: 20px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
position: absolute;
}
JavaScript 部分
接下来,我们在 script.js
中编写游戏的主要逻辑。
1. 初始化 Canvas 和变量
我们首先获取 Canvas 元素及其上下文,并定义游戏所需的一些变量。
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
const restartButton = document.getElementById("restartButton");
const gridSize = 20; // 格子大小
const rows = canvas.height / gridSize;
const cols = canvas.width / gridSize;
2. 初始化游戏
创建 initGame
函数来初始化游戏状态:
function initGame() {
snake = [{ x: cols / 2, y: rows / 2 }, { x: cols / 2 + 1, y: rows / 2 }];
food = {
x: Math.floor(Math.random() * cols),
y: Math.floor(Math.random() * rows),
};
direction = { x: 1, y: 0 };
lastDirection = { x: 1, y: 0 };
gameOver = false;
restartButton.style.display = "none";
gameLoop();
}
3. 绘制游戏元素
我们需要两个函数来绘制蛇和食物:
function drawCell(x, y, color) {
ctx.fillStyle = color;
ctx.fillRect(x * gridSize, y * gridSize, gridSize, gridSize);
ctx.strokeStyle = "#000";
ctx.lineWidth = 2; // 可以根据需要调整
ctx.strokeRect(x * gridSize, y * gridSize, gridSize, gridSize);
}
function drawSnake() {
snake.forEach((part) => drawCell(part.x, part.y, "#409EFF"));
}
function drawFood() {
drawCell(food.x, food.y, "#E6A23C");
}
4. 更新蛇的位置
创建 updateSnake
函数来更新蛇的位置,并检查它是否吃到食物或撞到墙及自身:
function updateSnake() {
const head = { x: snake[0].x + direction.x, y: snake[0].y + direction.y };
if (head.x === food.x && head.y === food.y) {
food = {
x: Math.floor(Math.random() * cols),
y: Math.floor(Math.random() * rows),
};
} else {
snake.pop();
}
snake.unshift(head);
// 撞墙或撞到自己
if (
head.x < 0 ||
head.x >= cols ||
head.y < 0 ||
head.y >= rows ||
snake.slice(1).some((part) => part.x === head.x && part.y === head.y)
) {
gameOver = true;
}
lastDirection = direction;
}
5. 游戏循环
创建 gameLoop
函数来处理游戏的绘制和更新:
function gameLoop() {
if (!gameOver) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawFood();
updateSnake();
drawSnake();
setTimeout(gameLoop, 100);
} else {
ctx.font = "100px Arial";
ctx.fillStyle = "#F56C6C";
ctx.fillText("Game Over", canvas.width / 4, canvas.height / 2);
restartButton.style.display = "block"; // 显示重新开始按钮
}
}
6. 处理用户输入
添加键盘事件监听来控制蛇的移动方向:
window.addEventListener("keydown", (event) => {
switch (event.key) {
case "ArrowUp":
if (lastDirection.y === 0) direction = { x: 0, y: -1 };
break;
case "ArrowDown":
if (lastDirection.y === 0) direction = { x: 0, y: 1 };
break;
case "ArrowLeft":
if (lastDirection.x === 0) direction = { x: -1, y: 0 };
break;
case "ArrowRight":
if (lastDirection.x === 0) direction = { x: 1, y: 0 };
break;
}
});
7. 重新开始游戏
最后,创建一个函数用于重新启动游戏:
function restartGame() {
initGame(); // 重新启动游戏
}
initGame(); // 启动游戏
总结
通过这篇博客,你学习了如何使用 HTML5 Canvas 和 JavaScript 来实现一个简单的贪吃蛇小游戏。我们展示了如何绘制游戏元素,处理用户输入,并管理游戏状态。希望这个项目能帮助你对游戏开发有更深入的理解,并激发你进行更多有趣的项目开发!