前言
贪吃蛇游戏是经典的小游戏,也是学习前端JS的一个很好的练习项目。在本教程中,我们将使用 JavaScript 来逐步构建一个贪吃蛇游戏。我们会从创建游戏区域开始,逐步添加蛇的移动、食物的生成以及游戏逻辑等功能。
? 作者简介:程序员小豪,全栈工程师,热爱编程,曾就职于蔚来、腾讯,现就职于某互联网大厂,技术栈:Vue、React、Python、Java
? 本文收录于小豪的前端系列专栏,后续还会更新前端入门以及前端面试的一些相关文章,手把手带你从零学习前端到面试找工作,并如果有想进入前端领域工作的同学,这个前端专栏会对你有所帮助,欢迎关注起来呀
? 本人也会持续的去关注AIGC以及人工智能领域
的一些动向并总结到博客中,大家感兴趣的可以关注一下我的人工智能专栏
? 云原生的入门学习系列,大家有兴趣的可以看一看
步骤1:创建文件
我们需要创建三个文件index.html
、styles.css
、script.js
,index.html用于放置我们界面dom,styles.css用于开发样式,script.js用于放置实现贪吃蛇的逻辑。
步骤2:创建游戏区域
首先,我们需要一个游戏区域来展示游戏。在 HTML 文件中创建一个
元素,用于表示游戏区域。然后,使用 CSS 来设置该元素的样式,使其成为一个矩形的游戏画布。
<!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="styles.css"></head><body> <div class="game-area"></div> <script src="script.js"></script></body></html>
/* styles.css */.game-area { width: 400px; height: 400px; border: 2px solid #000;}
可以看到,我们在styles.css设置了这个游戏区域的宽度和高度为400px,还设置了一个2px的黑色边框
步骤3:初始化蛇的位置
在 script.js 文件中,我们将初始化蛇的初始位置。定义一个表示蛇身的数组,每个元素代表蛇的一个部分,然后设置蛇的初始位置。
// script.jsconst gameArea = document.querySelector('.game-area');const snake = [{ x: 2, y: 2 }]; // 初始位置// 初始化蛇的位置function initializeSnake() { snake.forEach(segment => { const snakeSegment = document.createElement('div'); snakeSegment.classList.add('snake'); snakeSegment.style.left = segment.x * 20 + 'px'; snakeSegment.style.top = segment.y * 20 + 'px'; gameArea.appendChild(snakeSegment); });}initializeSnake();
/* styles.css */.snake { width: 20px; height: 20px; background-color: green; position: absolute;
知识点:
document.querySelector('.game-area')
用于获取游戏区域的整个dom蛇的身体我们用一个数组来实现,每一截区域都有一个坐标我们根据snake这个数组用document.createElement('div')
给蛇的每一截身体渲染一个div元素在styles.css里使用background-color: green;
将蛇的身体设置为绿色在styles.css里使用position: absolute;
设置蛇的每一截取的身体为绝对定位。然后通过js设置每一截身体的dom的left
和top
,从而设置其位置步骤3:移动蛇
接下来,我们将实现蛇的移动功能。我们会添加一个监听键盘事件,当玩家按下方向键时,蛇将根据所选择的方向移动。
// script.jslet direction = "right"; // 初始方向document.addEventListener("keydown", (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 moveSnake() { const head = { x: snake[0].x, y: snake[0].y }; console.log(direction); // 根据方向更新蛇头位置 if (direction === "up") { head.y--; } else if (direction === "down") { head.y++; } else if (direction === "left") { head.x--; } else if (direction === "right") { head.x++; } console.log(head); // 更新蛇的位置 snake.unshift(head); // 移除蛇尾 const removedSegment = snake.pop(); // 更新蛇身的样式 const newHead = document.createElement("div"); newHead.classList.add("snake"); newHead.style.left = head.x * 20 + "px"; newHead.style.top = head.y * 20 + "px"; gameArea.insertBefore(newHead, gameArea.firstChild); // 移除蛇尾的样式 if (removedSegment) { const elementsToDelete = document.querySelectorAll(".snake"); if (elementsToDelete.length > 0) { const lastElement = elementsToDelete[elementsToDelete.length - 1]; gameArea.removeChild(lastElement); } }}setInterval(moveSnake, 1000); // 每1000毫秒移动一次
在这个步骤中,我们使用了定时器来连续地移动蛇。通过按下方向键,你可以控制蛇的移动方向。
这里我们通过 gameArea.insertBefore(newHead, gameArea.firstChild);
在gameArea的子节点的最前面插入一个新的节点,并通过gameArea.removeChild(lastElement);
删除最后一个子节点。
最后,通过以下代码,来监听按键行为,来控制贪吃蛇前进方向:
document.addEventListener("keydown", (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"; }});
步骤4:生成食物
接下来,我们将实现食物的生成功能。每当蛇吃掉食物后,我们将随机生成一个新的食物位置。
// script.jslet food = { x: 5, y: 5 }; // 初始食物位置function generateFood() { let foodItem = document.querySelectorAll(".food"); if (foodItem.length >= 1) { gameArea.removeChild(foodItem[0]); } food.x = Math.floor(Math.random() * 20); // 随机生成 x 坐标 food.y = Math.floor(Math.random() * 20); // 随机生成 y 坐标 if (food.x <= 0) { food.x = 1; } else if (food.x >= 20) { food.x = 19; } if (food.y <= 0) { food.y = 1; } else if (food.y >= 20) { food.y = 19; } // 创建食物元素 const foodElement = document.createElement("div"); foodElement.classList.add("food"); foodElement.style.left = food.x * 20 + "px"; foodElement.style.top = food.y * 20 + "px"; gameArea.appendChild(foodElement);}generateFood();
/* styles.css */.food { width: 20px; height: 20px; background-color: red; position: absolute;}
步骤5:检测碰撞与游戏逻辑
最后,我们需要检测蛇是否与食物相撞以及是否撞墙,同时还需要处理游戏结束的情况。
// script.jsfunction checkCollision() { const head = snake[0]; // 检查是否撞墙 if (head.x < 0 || head.x >= 20 || head.y < 0 || head.y >= 20) { clearInterval(gameInterval); // 停止游戏 alert("游戏结束!"); return true; } // 检查是否与食物相撞 console.log("head:", head.x, head.y); console.log("food:", food.x, food.y); if (head.x === food.x && head.y === food.y) { // 吃掉食物,增加蛇的长度 let x, y; // 判断蛇尾增加的方向 if (direction === "right") { x = snake[snake.length - 1].x - 1; y = snake[snake.length - 1].y; } else if (direction === "left") { x = snake[snake.length - 1].x + 1; y = snake[snake.length - 1].y; } else if (direction === "top") { x = snake[snake.length - 1].x; y = snake[snake.length - 1].y + 1; } else { x = snake[snake.length - 1].x; y = snake[snake.length - 1].y - 1; } snake.push({ x, y }); const newTail = document.createElement("div"); newTail.classList.add("snake"); newTail.style.left = x * 20 + "px"; newTail.style.top = y * 20 + "px"; gameArea.appendChild(newTail); generateFood(); } // 检查是否与自身相撞 for (let i = 1; i < snake.length; i++) { if (head.x === snake[i].x && head.y === snake[i].y) { clearInterval(gameInterval); // 停止游戏 alert("游戏结束!"); return true; } } return false;}let gameInterval = setInterval(() => { if (!checkCollision()) { moveSnake(); }}, 1000);
涉及知识点:
通过direction
来判断贪吃蛇吃到食物后变长的方向alert
是用于弹出提示框的JS api 这样,我们就完成了一个简单的贪吃蛇游戏!通过上述步骤,我们从创建游戏区域、初始化蛇的位置,到实现蛇的移动、食物的生成,最终加入碰撞检测和游戏逻辑,完成了一个可玩的贪吃蛇游戏。
总结
通过这个项目,你不仅可以学习如何使用 JavaScript 来实现一个小游戏,还可以熟练学习js操作dom、数据的常用方法、定时器setInterval、css样式、事件监听器以及实现需求的逻辑思维等等知识,对前面学习的一些理论知识进行了实践,相信你跟着一套教程下来会对前面学习到的知识有更深的理解。
后续我们这个前端专栏还会讲述ES6、垃圾回收、js算法技巧、Vue入门实战、React实战、前端面试题等等文章,如果您感兴趣的话,欢迎点赞三连并关注我以及我的前端专栏,我们下期文章再见。