运行效果图:
代码展示:
index.html
<!DOCTYPE html>
<html>
<head>
<title>贪吃蛇游戏</title>
<style>
#game-board {
width: 400px;
height: 400px;
border: 1px solid #000;
position: relative;
}
.snake-dot,
.food-dot {
width: 20px;
height: 20px;
background-color: #000;
position: absolute;
}
.food-dot {
background-color: red;
}
</style>
</head>
<body>
<div id="score">得分: 0</div>
<div id="game-board"></div>
<script src="./js/snake.js"></script>
</body>
</html>
snake.js
// 游戏设置
var tileSize = 20; // 单个方块的大小
var initialSpeed = 200; // 初始速度(毫秒)
var speedMultiplier = 1; // 加速倍数
var direction = "right"; // 初始方向
// 初始化贪吃蛇
var snake = [
{ top: 0, left: 0 },
];
// 当前食物的位置
var food = {};
// 游戏循环计时器
var gameLoop;
// 游戏是否结束
var gameOver = false;
// 游戏板元素
var gameBoard = document.getElementById("game-board");
// 监听方向键按下事件
document.addEventListener("keydown", function (event) {
if (event.key === "ArrowUp" && direction !== "down") {
direction = "up";
} else if (event.key === "ArrowDown" && direction !== "up") {
direction = "down";
} else if (event.key === "ArrowLeft" && direction !== "right") {
direction = "left";
} else if (event.key === "ArrowRight" && direction !== "left") {
direction = "right";
}
});
// 开始游戏
function startGame() {
createFood();
document.getElementById("score").innerText = "得分: " + (snake.length - 1);
gameLoop = setInterval(moveSnake, initialSpeed);
}
// 创建食物
function createFood() {
// 随机食物的位置
// gameBoard.offsetHeight 规定的宽高
var top = Math.floor(Math.random() * (gameBoard.offsetHeight / tileSize)) * tileSize;
var left = Math.floor(Math.random() * (gameBoard.offsetWidth / tileSize)) * tileSize;
food = { top: top, left: left };
// 创建
var foodElement = document.createElement("div");
foodElement.className = "food-dot";
foodElement.style.top = food.top + "px";
foodElement.style.left = food.left + "px";
gameBoard.appendChild(foodElement);
}
// 移动贪吃蛇
function moveSnake() {
// Object.assign() 用于将一个或多个源对象的属性复制到目标对象中
var head = Object.assign({}, snake[0]);
// 移动,通过定时器移动
if (direction === "up") {
head.top -= tileSize;
} else if (direction === "down") {
head.top += tileSize;
} else if (direction === "left") {
head.left -= tileSize;
} else if (direction === "right") {
head.left += tileSize;
}
if (checkCollision(head)) {
gameOver = true;
clearInterval(gameLoop);
if (gameOver) {
var restart = confirm("游戏结束!你的分数为:" + (snake.length - 1) + "。是否重新开始?");
if (restart) {
snake = [
{ top: 0, left: 0 }
];
direction = "right";
initialSpeed = 200;
gameOver = false;
// 清除食物
let foodElement = document.querySelector(".food-dot");
gameBoard.removeChild(foodElement);
startGame()
return
}
}
}
//元素插入到数组的开头
snake.unshift(head);
if (head.top === food.top && head.left === food.left) {
// 删除已经被吃掉的食物
var foodElement = document.querySelector(".food-dot");
gameBoard.removeChild(foodElement);
// 创建新的食物
createFood();
} else {
// 移除数组的最后一个元素
snake.pop();
}
updateSnake();
}
// 更新贪吃蛇的显示
function updateSnake() {
// 清除之前的位置
var snakeDots = document.getElementsByClassName("snake-dot");
while (snakeDots.length > 0) {
snakeDots[0].parentNode.removeChild(snakeDots[0]);
}
// 绘制当前位置
for (var i = 0; i < snake.length; i++) {
var snakeElement = document.createElement("div");
snakeElement.className = "snake-dot";
snakeElement.style.top = snake[i].top + "px";
snakeElement.style.left = snake[i].left + "px";
gameBoard.appendChild(snakeElement);
}
document.getElementById("score").innerText = "得分: " + (snake.length - 1);
}
// 检查是否与边界或自身碰撞
function checkCollision(position) {
// 是否与边界碰撞
if (
position.top < 0 ||
position.top >= gameBoard.offsetHeight ||
position.left < 0 ||
position.left >= gameBoard.offsetWidth
) {
return true;
}
// 自身碰撞
for (var i = 1; i < snake.length; i++) {
if (position.top === snake[i].top && position.left === snake[i].left) {
return true;
}
}
return false;
}
// 启动游戏
startGame();