【前端|JS实战第1篇】使用JS来实现属于自己的贪吃蛇游戏!

news/2024/5/9 23:26:15/文章来源:https://blog.csdn.net/A_D_H_E_R_E/article/details/132386189

在这里插入图片描述

前言

贪吃蛇游戏是经典的小游戏,也是学习前端JS的一个很好的练习项目。在本教程中,我们将使用 JavaScript 来逐步构建一个贪吃蛇游戏。我们会从创建游戏区域开始,逐步添加蛇的移动、食物的生成以及游戏逻辑等功能。


🚀 作者简介:程序员小豪,全栈工程师,热爱编程,曾就职于蔚来、腾讯,现就职于某互联网大厂,技术栈:Vue、React、Python、Java
🎈 本文收录于小豪的前端系列专栏,后续还会更新前端入门以及前端面试的一些相关文章,手把手带你从零学习前端到面试找工作,并如果有想进入前端领域工作的同学,这个前端专栏会对你有所帮助,欢迎关注起来呀
🌼 本人也会持续的去关注AIGC以及人工智能领域的一些动向并总结到博客中,大家感兴趣的可以关注一下我的人工智能专栏
🌊 云原生的入门学习系列,大家有兴趣的可以看一看

步骤1:创建文件

我们需要创建三个文件index.htmlstyles.cssscript.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.js
const 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的lefttop,从而设置其位置
    在这里插入图片描述

步骤3:移动蛇

接下来,我们将实现蛇的移动功能。我们会添加一个监听键盘事件,当玩家按下方向键时,蛇将根据所选择的方向移动。

// script.js
let 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.js
let 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.js
function 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实战、前端面试题等等文章,如果您感兴趣的话,欢迎点赞三连并关注我以及我的前端专栏,我们下期文章再见。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_159130.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#面向对象程序设计之变量的作用域,深入浅出 入门和进阶教程3

1、效果镇楼: 最近忒忙了!真的忙到不可开交的呢,繁杂业务的处理真的不是您,我个人想象的样子,完全比您个人想象的要复杂至少三倍以上的难度!也是客观事实。 菜鸟程序员面临的客观残酷现实!尤其您这个年龄阶段,实在是堪忧,尴尬的很啊,非常严峻的形势,也可以说特别严峻…

Python写一个创意五子棋游戏

前言 在本教程中&#xff0c;我们将使用Python写一个创意五子棋游戏 &#x1f4dd;个人主页→数据挖掘博主ZTLJQ的主页 个人推荐python学习系列&#xff1a; ☄️爬虫JS逆向系列专栏 - 爬虫逆向教学 ☄️python系列专栏 - 从零开始学python 首先 GomokuGame 类的构造函数 __ini…

文件上传xxx

本地保存文件 将文件保存到服务器本地硬盘中 max-request-size 多个文件总大小不能大于100M PostMapping("/upload")public Result upload(String username,Integer age,MultipartFile image) throws IOException {log.info("用户名:{},牛叔&#xff1a;{},文件…

【机器学习实战】朴素贝叶斯:过滤垃圾邮件

【机器学习实战】朴素贝叶斯&#xff1a;过滤垃圾邮件 0.收集数据 这里采用的数据集是《机器学习实战》提供的邮件文件&#xff0c;该文件有ham 和 spam 两个文件夹&#xff0c;每个文件夹中各有25条邮件&#xff0c;分别代表着 正常邮件 和 垃圾邮件。 这里需要注意的是需要…

蓝牙 - BLE SPP的设计策略(Serial over BLE strategy)

在开发 BLE 连接产品的过程中&#xff0c;你可能会有这样的疑问&#xff1a;"Serial profile在哪里&#xff1f;也许你以为你在蓝牙技术联盟网站上滚动浏览长长的profile列表时错过了它。又或者&#xff0c;你根本就没去看&#xff0c;而是准备选择更快的方法&#xff0c;…

人脸识别技术在社会安全与便利中的应用

引言&#xff1a;随着人工智能的快速发展&#xff0c;人脸识别技术已经成为一种实时、高效的身份验证和安全监控手段。它的广泛应用可以帮助识别犯罪嫌疑人、寻找失踪人口等&#xff0c;为社会安全和公共利益做出了重要贡献。本文将详细探讨人脸识别技术的原理、应用&#xff0…

【高级IO】- 五种 IO 模型 | 多路转接 - select

IO的基本概念 I/O&#xff08;Input / output&#xff09;就是输入和输出&#xff0c;在冯诺依曼体系中&#xff0c;将数据从输入设备拷贝到内存叫做输入&#xff0c;将数据从内存拷贝到输出设备叫做输出。 对文件进行的读写操作本质就是一种IO&#xff0c;文件IO对应的外设就…

Linux命令200例:clock的具体应用,设置系统的时钟时间、硬件时钟和定时器等相关信息

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

前端对文件转换处理的一些常用方法

文章目录 0&#xff0c;前言1&#xff0c;将图片的url网络链接(http://) 转为base64格式2&#xff0c;将base64的图片数据转换为file文件3&#xff0c;将以base64的图片数据转换为Blob4&#xff0c;将file文件转化为base645&#xff0c;将file文件转换为Blob6&#xff0c;获取文…

微信公众平台发布小程序流程

最近因为部署小程序&#xff0c;学习了下如何部署小程序 1. 取消不检验合法域名并上传小程序 建议在小程序上传之前&#xff0c;先取消不校验合法域名并真机调试下。 2. 登录微信公众平台 登录微信公众平台 3. 设置服务器域名 在开放->开发管理->开发设置找到服务器…

三维重建_基于图像的三维重建_面片/光度一致性

参考: 深蓝学院 基于图像的三维重建 1. 三维重建的流程回顾 基于深度图的三维重建:从无序图像获取稀疏点云和位姿,然后进行多视角立体重建。 多视角立体重建包含:(输入稀疏点云、各个图像位姿、图像)先进行立体对(3D-2D,2D-2D)的选择,然后计算深度图,接着进行深度图…

【C语言】C语言用数组算平均数,并输出大于平均数的数

题目 让用户输入一系列的正整数&#xff0c;最后输入“-1”表示输入结束&#xff0c;然后程序计算出这些数的平均数&#xff0c;最后输出输入数字的个数和平均数以及大于平均数的数 代码 #include<stdio.h> int main() {int x;double sum 0;int cnt 0;int number[100…

使用 AI 将绘画和照片转换为动画

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建可二次编辑器的3D应用场景 华盛顿大学和Facebook的研究人员最近发表了一篇论文&#xff0c;展示了一种基于深度学习的系统&#xff0c;可以将静止图像和绘画转换为动画。称为照片唤醒的算法使用卷积神经网络从单个静止图像以 …

WPF入门到精通:1.新建项目及项目结构

WPF&#xff08;Windows Presentation Foundation&#xff09;是一种用于创建 Windows 应用程序的技术&#xff0c;它可以通过 XAML&#xff08;Extensible Application Markup Language&#xff09;和 C# 或其他 .NET 语言来实现。WPF 提供了许多强大的 UI 控件和样式&#xf…

如何找到一个数的所有质因数,以及如何快速判断一个数是不是质数

前情介绍 今天遇到一个需求&#xff1a;找到一个数所有的质因数。 初步解决 先定义一个判断质数的函数&#xff1a; def is_Prime(number):i 2count 0while i < number:if number % i 0 :count 1i 1if count > 0:return Falseelse:return True 接着定义一个寻找质…

Java-图书登录系统的实现

实现效果 它将面对 管理员 和 普通用户 两种用户来提供服务&#xff0c;并且各自的服务并不相同。 实现思路 一般写项目&#xff0c;每个独立的功能都会写成一个类&#xff0c;而有关联的功能&#xff0c;都会将多个类存放在一个包中&#xff0c;此项目我们将用 3 个包来体现我…

链表之第三回

欢迎来到我的&#xff1a;世界 该文章收入栏目&#xff1a;链表 希望作者的文章对你有所帮助&#xff0c;有不足的地方还请指正&#xff0c;大家一起学习交流 ! 目录 前言第一题&#xff1a;判断是否为环形链表第二题&#xff1a;找到两条链表的相交点第三题&#xff1a;返回…

P17~P18 电路定理 电路中难得的精彩到极致的电路理论

特勒根定理、互易定理、对偶定理比较难&#xff0c;非常重要&#xff0c;因为他们可以解决其他定理无法解决的问题。 1、特勒根定理1——个人感觉像能量守恒 特勒根定理与基尔霍夫定理齐名&#xff0c;与拓扑结构有关。都适用于任何线性非线性&#xff0c;时变的非时变的元件…

分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测

分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测 目录 分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测 程序设计 完整源码和数据获取方式&#xff1a; …

网站老域名跳转到新域名有哪些方法?内网穿透内网主机让外网访问

在网站服务器变更及本地主机搭建时&#xff0c;我们经常会遇到老域名地址跳转到新URL的配置&#xff0c;一些朋友还会面对无公网IP让外网访问的问题。今天我们来了解下网站老域名跳转到新域名有哪些方法&#xff0c;以及如何通过内网穿透实现内网主机让外网访问。 网站老域名跳…