JavaScript学习最后一章节(小练习)
JavaScript学习最后一章节(小练习)
- dom的练习
- 贪吃蛇
背景
首先感谢尚硅谷的讲师-李立超老师,看完了他的javascript课程,让我巩固了基础。原本我作为一个后端java开发的人员,对这些东西使用也是一知半解。只停留在用的基础上。
vue2 -> vue3 -> css2 -> css3 -> javascript 这是我的一个学习路线
学完javascript可以做什么
JavaScript(JS)是一种功能强大的脚本语言,其应用场景涵盖前端、后端及移动端开发,以下是其主要用途:
网页开发(前端)
- 动态交互:通过DOM操作实现页面内容、样式和结构的实时修改,例如点击按钮改变文本、滑动页面触发动画等。 12
- 表单验证:在数据提交前进行客户端验证,减少服务器压力并提升用户体验。 23
- 异步通信:支持AJAX/Fetch等技术实现页面数据更新不刷新。 23
- **单页应用(SPA)**:配合React、Vue等框架构建交互性强的Web应用。 2
服务器端开发
- Node.js应用:用于构建Web服务器(如Express)、API接口(RESTful/GraphQL)及微服务架构。 24
- 数据库操作:支持MySQL、MongoDB等数据库的增删改查。 23
- 文件处理:实现文件读写、上传下载等功能。 24
移动端开发
- 原生应用:通过Cordova等框架将JS代码转化为原生应用代码。 2
- 混合开发:结合HTML/CSS实现跨平台界面设计。 2
其他场景
- 客户端验证:检测浏览器信息、控制Cookies等。 4
- 游戏开发:通过Phaser等框架实现交互性游戏。 2
- 数据分析:配合D3等工具实现数据可视化。
1、练习1
定时器自动切换图片,轮播图的实现
代码示例
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>小练习-定时器自动切换图片.</title><style>.outer {width: 640px;margin: 30px auto;text-align: center;}</style>
</head>
<body><div class="outer"><h2 class="topinf">图片共计:() 张,目前正在切换第:()张</h2><div class="img-wrapper"><img src="./images/1.png" alt=""></div><div class="btn-wrapper"><button type="button" id="prev">上一张</button><button type="button" id="auto">自动切换</button><button type="button" id="next">下一张</button></div></div><script>// img元素信息const imgEl = document.getElementsByTagName("img")[0];// 点击的下标元素let index = 0;const imgArr = ["./images/1.png", "./images/2.png", "./images/3.png", "./images/4.png"]// 获取 btn 元素const btnPre = document.getElementById('prev');// 下一张const btnNext = document.getElementById('next');// 提示信息const tipInfEl = document.getElementsByClassName("topinf")[0];tipInf();btnPre.onclick = function() {index --;// 上一张if(index < 0) {index = imgArr.length - 1;}// 关闭定时器clearTimeout(timer);imgEl.src = imgArr[index];tipInf();}btnNext.onclick = function () {index++;// 下一张if (index > imgArr.length - 1) {index = 0;}// 关闭定时器clearTimeout(timer);imgEl.src = imgArr[index];tipInf();}// 提示信息function tipInf() {tipInfEl.textContent = ` 图片共计:(${imgArr.length}) 张,目前正在切换第:(${index+1})张`}// 图片自动切换方式1 const autoButton = document.getElementById("auto");// autoButton.onclick = function() {// //开启定时器,切换图片// setInterval(() => {// // 切换下一张图片// btnNext.click(); // }, 1000);// }//定时器idlet timer;// 图片自动切换二 autoButton.onclick = function() {if(autoButton.textContent === '停止定时器') {clearTimeout(timer);autoButton.textContent = '自动切换';return;}timer = setTimeout(function fn() {autoButton.textContent = '停止定时器';btnNext.click(); timer = setTimeout(fn,1000);}, 0);}</script></body>
效果
2、练习2
图片切换优化提前加载,优化轮播图
代码示例
<title>小练习-图片切换优化提前加载</title><style>* {margin: 0;padding: 0;}img {vertical-align: top;}ul {list-style: none;}.outer {width: 640px;height: 390px;margin: 100px auto;}.img-list {height: 390px;}.img-list li {position: absolute;opacity: 0;transition: opacity .8s;}li.current{z-index: 1;opacity: 1;}</style>
</head>
<body><div class="outer"><ul class="img-list"><li class="current"><a href="#"><img src="images/1.png" alt="1"></a></li><li><a href="#"><img src="images/2.png" alt="1"></a></li><li><a href="#"><img src="images/3.png" alt="1"></a></li><li><a href="#"><img src="images/4.png" alt="1"></a></li></ul></div><script>//自动切换图片document.getElementsByClassName("img-list");setTimeout(function auto(){//获取当前显示的图片const currnetEl = document.querySelector(".img-list .current");//获取下一个图片const nextEl = currnetEl.nextElementSibling || document.querySelector(".img-list li");currnetEl.classList.remove("current");// 下一张图片增加样式nextEl.classList.add("current");setTimeout(auto,2000)}, 2000);</script></body>
效果
3、练习3
图片切换优化提前加载
代码示例
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>小练习-图片切换优化提前加载</title><style>* {margin: 0;padding: 0;}img {vertical-align: top;}ul {list-style: none;}.outer {width: 640px;height: 390px;margin: 100px auto;position: relative;}.img-list {height: 390px;}.img-list li {position: absolute;opacity: 0;transition: opacity .8s;}li.current{z-index: 1;opacity: 1;}/**箭头样式*/.prev-next a {font-size: 60px;color: red;color: white;font-weight: bold;text-decoration: none;position: absolute;height: 60px;top: 0;bottom: 0;margin:auto;z-index: 2;opacity: .5;}.prev-next a:hover {opacity: 1;}#next{right: 0;}</style>
</head>
<body><div class="outer"><ul class="img-list"><li class="current"><a href="#"><img src="images/1.png" alt="1"></a></li><li><a href="#"><img src="images/2.png" alt="1"></a></li><li><a href="#"><img src="images/3.png" alt="1"></a></li><li><a href="#"><img src="images/4.png" alt="1"></a></li></ul><!-- 添加切换按钮 --><div class="prev-next"><a href="javascript:;" id="prev"> < </a><a href="javascript:;" id="next"> > </a></div></div><script>//自动切换图片document.getElementsByClassName("img-list");setTimeout(function auto(){//获取当前显示的图片const currnetEl = document.querySelector(".img-list .current");//获取下一个图片const nextEl = currnetEl.nextElementSibling || document.querySelector(".img-list li");currnetEl.classList.remove("current");// 下一张图片增加样式nextEl.classList.add("current");setTimeout(auto,2000)}, 2000);const prevButton = document.getElementById("prev");const nextButton = document.getElementById("next");//下一张nextButton.onclick = function() {//获取当前显示的图片const currnetEl = document.querySelector(".img-list .current");//获取下一个图片const nextEl = currnetEl.nextElementSibling || document.querySelector(".img-list li");currnetEl.classList.remove("current");// 下一张图片增加样式nextEl.classList.add("current");}//上一张prevButton.onclick = function() {//获取当前显示的图片const currnetEl = document.querySelector(".img-list .current");//获取上一个元素const nextEl = currnetEl.previousElementSibling|| document.querySelector(".img-list li:last-child");currnetEl.classList.remove("current");// 切换显示状态nextEl.classList.add("current");}</script></body>
效果
4、练习4
小练习-图片切换函数提取
代码示例
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>小练习-图片切换优化提前加载</title><style>* {margin: 0;padding: 0;}img {vertical-align: top;}ul {list-style: none;}.outer {width: 640px;height: 390px;margin: 100px auto;position: relative;}.img-list {height: 390px;}.img-list li {position: absolute;opacity: 0;transition: opacity .8s;}li.current{z-index: 1;opacity: 1;}/**箭头样式*/.prev-next a {font-size: 60px;color: red;color: white;font-weight: bold;text-decoration: none;position: absolute;height: 60px;top: 0;bottom: 0;margin:auto;z-index: 2;opacity: .5;}.prev-next a:hover {opacity: 1;}#next{right: 0;}</style>
</head>
<body><div class="outer"><ul class="img-list"><li class="current"><a href="#"><img src="images/1.png" alt="1"></a></li><li><a href="#"><img src="images/2.png" alt="1"></a></li><li><a href="#"><img src="images/3.png" alt="1"></a></li><li><a href="#"><img src="images/4.png" alt="1"></a></li></ul><!-- 添加切换按钮 --><div class="prev-next"><a href="javascript:;" id="prev"> < </a><a href="javascript:;" id="next"> > </a></div></div><script>//自动切换图片document.getElementsByClassName("img-list");//闭包const toggleChange = (function() {let timer = null;// 自动切换提取到一个函数里面return () => {if(timer === null) {//开启切换图片timer = setTimeout(function auto() {//改变图片changeImg("next");timer = setTimeout(auto,2000)},2000);} else {clearTimeout(timer);timer = null;}};})()//上来自动开启自动切换toggleChange();const prevButton = document.getElementById("prev");const nextButton = document.getElementById("next");//下一张nextButton.onclick = function() {changeImg("next")}//上一张prevButton.onclick = function() {changeImg("pre")}// 优化点 1、重复代码,需要精炼函数// 2、当手动点击时候,自动停一下// dir 切换图片的方向 // 1. next// 2. prefunction changeImg(dir) {//获取当前显示的图片const currnetEl = document.querySelector(".img-list .current");//获取下一个图片let nextEl;if(dir === 'next') {nextEl = currnetEl.nextElementSibling || document.querySelector(".img-list li");} else if (dir === 'pre') {nextEl = currnetEl.previousElementSibling|| document.querySelector(".img-list li:last-child");}currnetEl.classList.remove("current");// 下一张图片增加样式nextEl.classList.add("current");}// 图片的自动切换关闭和开启const outerEl = document.getElementsByClassName("outer")[0];//鼠标进去的时候outerEl.onmouseenter = () => {toggleChange();}//鼠标离开的时候outerEl.onmouseleave = () => {toggleChange();}</script></body>
效果
5、练习5
图片切换增加导航点
代码示例
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>小练习-图片切换增加导航点</title><style>* {margin: 0;padding: 0;}img {vertical-align: top;}ul {list-style: none;}.outer {width: 640px;height: 390px;margin: 100px auto;position: relative;}.img-list {height: 390px;}.img-list li {position: absolute;opacity: 0;transition: opacity .8s;}li.current{z-index: 1;opacity: 1;}/**箭头样式*/.prev-next a {font-size: 60px;color: red;color: white;font-weight: bold;text-decoration: none;position: absolute;height: 60px;top: 0;bottom: 0;margin:auto;z-index: 2;opacity: .5;}.prev-next a:hover {opacity: 1;}#next{right: 0;}/**导航点*/.dot {position: absolute;display: flex;justify-content: center;z-index: 3;left: 0;right: 0;bottom: 5px;margin: 0 auto;}.dot a {float: left;width: 15px;height: 15px;border-radius: 50%;background-color: #fff;margin: 8px;opacity: .5;}.dot a:hover,.dot .active {opacity: 1;background-color: aqua;}</style>
</head>
<body><div class="outer"><ul class="img-list"><li class="current"><a href="#"><img src="images/1.png" alt="1"></a></li><li><a href="#"><img src="images/2.png" alt="2"></a></li><li><a href="#"><img src="images/3.png" alt="3"></a></li><li><a href="#"><img src="images/4.png" alt="4"></a></li><li><a href="#"><img src="images/5.png" alt="5"></a></li></ul><!-- 添加切换按钮 --><div class="prev-next"><a href="javascript:;" id="prev"> < </a><a href="javascript:;" id="next"> > </a></div><div class="dot"><a href="javascript:;" class="active"></a><a href="javascript:;"></a><a href="javascript:;"></a><a href="javascript:;"></a><a href="javascript:;"></a></div></div><script>//自动切换图片document.getElementsByClassName("img-list");//闭包const toggleChange = (function() {let timer = null;// 自动切换提取到一个函数里面return () => {if(timer === null) {//开启切换图片timer = setTimeout(function auto() {//改变图片changeImg("next");timer = setTimeout(auto,2000)},2000);} else {clearTimeout(timer);timer = null;}};})()//上来自动开启自动切换toggleChange();const prevButton = document.getElementById("prev");const nextButton = document.getElementById("next");//下一张nextButton.onclick = function() {changeImg("next")}//上一张prevButton.onclick = function() {changeImg("pre")}//获取圆点const dotsEl = Array.from(document.querySelectorAll(".dot a"));//全部的图片li元素const imgArr = Array.from(document.querySelectorAll(".img-list li"));// 优化点 1、重复代码,需要精炼函数// 2、当手动点击时候,自动停一下// dir 切换图片的方向 // 1. next// 2. prefunction changeImg(dir) {//获取当前显示的图片const currnetEl = document.querySelector(".img-list .current");//获取下一个图片let nextEl;console.log(currnetEl.nextElementSibling )if(dir === 'next') {nextEl = currnetEl.nextElementSibling || imgArr[0];} else if (dir === 'pre') {nextEl = currnetEl.previousElementSibling || imgArr.at(-1);} else if (typeof dir === 'number') {nextEl = imgArr[dir];}currnetEl.classList.remove("current");// 下一张图片增加样式nextEl.classList.add("current");// 切换active const currentActive = document.querySelector(".dot .active");currentActive.classList.remove("active");//当前图片索引const curIndex = imgArr.indexOf(currnetEl);// 获取到当前要显示的圆点dotsEl[curIndex].classList.add("active");}// 图片的自动切换关闭和开启const outerEl = document.getElementsByClassName("outer")[0];//鼠标进去的时候outerEl.onmouseenter = () => {toggleChange();}//鼠标离开的时候outerEl.onmouseleave = () => {toggleChange();}//document.getElementsByClassName("dot")[0]document.getElementsByClassName("dot")[0].addEventListener("click",(event) => {const index = dotsEl.indexOf(event.target);if(index != -1) {changeImg(index);}})</script></body>
效果
6、贪吃蛇
用纯 js 写一个贪吃蛇的棋盘
1、布局部分
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>41.贪吃蛇-布局</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}#main {width: 360px;height: 420px;background-color: #b7d4a8;margin: 50px auto;border-radius: 20px;border: 10px solid #000;}#snake > div {width: 10px;height: 10px;background-color: #000;position: absolute;left: 30px;top: 30px;}#food {width: 10px;height: 10px;position: absolute;top: 100px;left: 100px;display: flex;flex-flow: wrap;}#food > div {height: 5px;width: 5px;background-color: #000;transform: rotate(45deg);}#stage {width: 304px;height: 304px;border: 2px solid #000;margin: 20px auto;position: relative;}#info {width: 304px;margin: 10px auto;display: flex;justify-content: space-between;font: bold 20px courier;}</style>
</head>
<body><div id="main"><!-- 舞台 --><div id="stage"><!-- 蛇 --><div id="snake"><div></div></div><!-- 食物 --><div id="food"><div></div><div></div><div></div><div></div></div></div><!-- 分数信息 --><div id="info"><div>SCORE:<span id="score"></span></div><div>LEVEL:1<span id="level"></span></div></div></div>
</body>
2、按建事件监听
监听键盘的上下左右事件,得到蛇需要移动的方向
js部分
<script>// 获取到蛇的domconst snake = document.getElementById("snake");// 获取到蛇的身体const snakes = snake.getElementsByTagName("div");//获取到蛇头const head = snake.getElementsByTagName("div")[0];// 通过按键事件 keydown keyup document.addEventListener("keydown",(event) => {// 通过事件对象可以获取到用的多个按键// console.log(event.keyCode);// console.log(event.key);switch (event.key) {case 'ArrowUp':// console.log("上")head.style.top = head.offsetTop - 10 + "px";break;case 'ArrowDown':// console.log("下")head.style.top = head.offsetTop + 10 + "px";break;case 'ArrowRight'://console.log("->")head.style.left = head.offsetLeft + 10 + "px";break;case 'ArrowLeft'://console.log("左")head.style.left = head.offsetLeft - 10 + "px";break;}});</script>
3、蛇的初步移动
<script>// 获取到蛇的domconst snake = document.getElementById("snake");// 获取到蛇的身体const snakes = snake.getElementsByTagName("div");//获取到蛇头const head = snake.getElementsByTagName("div")[0];//存储蛇的方向let dir;// 通过按键事件 keydown keyup document.addEventListener("keydown",(event) => {// 通过事件对象可以获取到用的多个按键// console.log(event.keyCode);// console.log(event.key);dir = event.key;});// 蛇的定时移动setTimeout(function move() {switch (dir) {case 'ArrowUp':// console.log("上")head.style.top = head.offsetTop - 10 + "px";break;case 'ArrowDown':// console.log("下")head.style.top = head.offsetTop + 10 + "px";break;case 'ArrowRight'://console.log("->")head.style.left = head.offsetLeft + 10 + "px";break;case 'ArrowLeft'://console.log("左")head.style.left = head.offsetLeft - 10 + "px";break;}// 300 毫秒执行一次,检查蛇的移动方向setTimeout(move, 300);}, 300);</script>
4、蛇的碰撞和食物检测
<script>// 获取到蛇的domconst snake = document.getElementById("snake");// 获取到蛇的身体const snakes = snake.getElementsByTagName("div");//获取到蛇头const head = snakes[0];//存储蛇的方向let dir;// 方向的枚举值const keyArr = ["ArrowUp","ArrowDown","ArrowRight","ArrowLeft"];// 获取食物的坐标位置const food = document.getElementById("food");// 通过按键事件 keydown keyup document.addEventListener("keydown",(event) => {// 通过事件对象可以获取到用的多个按键// console.log(event.keyCode);// console.log(event.key);if(keyArr.includes(event.key)) {dir = event.key;}});// 蛇的定时移动setTimeout(function move() {switch (dir) {case 'ArrowUp':// console.log("上")head.style.top = head.offsetTop - 10 + "px";break;case 'ArrowDown':// console.log("下")head.style.top = head.offsetTop + 10 + "px";break;case 'ArrowRight'://console.log("->")head.style.left = head.offsetLeft + 10 + "px";break;case 'ArrowLeft'://console.log("左")head.style.left = head.offsetLeft - 10 + "px";break;}//食物和蛇头是否重合if(head.offsetTop === food.offsetTop && head.offsetLeft === food.offsetLeft) {//1. 改变食物的位置foodRandom();//2. 增加蛇身体长度snake.insertAdjacentHTML("beforeend","<div/>")}// 300 毫秒执行一次,检查蛇的移动方向setTimeout(move, 300);}, 300);//随机出现食物位置foodRandom();//食物随机生成 // 取值范围 0 - 290 之间 10的倍数 ,横坐标/ 纵function foodRandom() {// 0 - 290 // 0 - 29 之间 * 10 const x = Math.floor(Math.random() * 30) * 10;// y 轴 const y = Math.floor(Math.random() * 30) * 10;food.style.left = x + "px";food.style.top = y + "px";}</script>
5、蛇整体移动
<script>// 获取到蛇的domconst snake = document.getElementById("snake");// 获取到蛇的身体const snakes = snake.getElementsByTagName("div");//存储蛇的方向let dir;// 方向的枚举值const keyArr = ["ArrowUp","ArrowDown","ArrowRight","ArrowLeft"];// 获取食物的坐标位置const food = document.getElementById("food");// 通过按键事件 keydown keyup document.addEventListener("keydown",(event) => {// 通过事件对象可以获取到用的多个按键// console.log(event.keyCode);// console.log(event.key);if(keyArr.includes(event.key)) {dir = event.key;}});// 蛇的定时移动setTimeout(function move() {//获取到蛇头let head = snakes[0];// 获取蛇头坐标let headX = head.offsetLeft;let headY = head.offsetTop;switch (dir) {case 'ArrowUp':// console.log("上")headY -= 10;break;case 'ArrowDown':// console.log("下")headY += 10;break;case 'ArrowRight'://console.log("->")headX += 10;break;case 'ArrowLeft'://console.log("左")headX -= 10;break;}//食物和蛇头是否重合if(head.offsetTop === food.offsetTop && head.offsetLeft === food.offsetLeft) {//1. 改变食物的位置foodRandom();//2. 增加蛇身体长度snake.insertAdjacentHTML("beforeend","<div/>")}//移动蛇的位置,蛇的尾部const tail = snakes[snakes.length -1];tail.style.left = headX + 'px';tail.style.top = headY + 'px';// 将尾巴移动蛇头位置snake.insertAdjacentElement("afterbegin",tail);// 300 毫秒执行一次,检查蛇的移动方向setTimeout(move, 300);}, 300);//随机出现食物位置foodRandom();//食物随机生成 // 取值范围 0 - 290 之间 10的倍数 ,横坐标/ 纵function foodRandom() {// 0 - 290 // 0 - 29 之间 * 10 const x = Math.floor(Math.random() * 30) * 10;// y 轴 const y = Math.floor(Math.random() * 30) * 10;food.style.left = x + "px";food.style.top = y + "px";}</script>
6、禁止掉头
<script>// 获取到蛇的domconst snake = document.getElementById("snake");// 获取到蛇的身体const snakes = snake.getElementsByTagName("div");//存储蛇的方向let dir;// 方向的枚举值const keyArr = ["ArrowUp","ArrowDown","ArrowRight","ArrowLeft"];// 获取食物的坐标位置const food = document.getElementById("food");// 身体超过2个,不能是相反的方向const arrowDisableMap = {ArrowUp: "ArrowDown",ArrowDow: "ArrowUp",ArrowRight: "ArrowLeft",ArrowLeft: "ArrowRight",}// 通过按键事件 keydown keyup document.addEventListener("keydown",(event) => {// 通过事件对象可以获取到用的多个按键// console.log(event.keyCode);// console.log(event.key);if(keyArr.includes(event.key)) {//console.log(snakes.length)// 获取当前方向 是否为掉头 小于2 并且不是掉头if(snakes.length < 2 || arrowDisableMap[dir] !== event.key) {dir = event.key;} }});/*** 1. 禁止掉头* 2. 积分* 3. 撞墙 */// 蛇的定时移动setTimeout(function move() {//获取到蛇头let head = snakes[0];// 获取蛇头坐标let headX = head.offsetLeft;let headY = head.offsetTop;switch (dir) {case 'ArrowUp':// console.log("上")headY -= 10;break;case 'ArrowDown':// console.log("下")headY += 10;break;case 'ArrowRight'://console.log("->")headX += 10;break;case 'ArrowLeft'://console.log("左")headX -= 10;break;}//食物和蛇头是否重合if(head.offsetTop === food.offsetTop && head.offsetLeft === food.offsetLeft) {//1. 改变食物的位置foodRandom();//2. 增加蛇身体长度snake.insertAdjacentHTML("beforeend","<div/>")}//移动蛇的位置,蛇的尾部const tail = snakes[snakes.length -1];tail.style.left = headX + 'px';tail.style.top = headY + 'px';// 将尾巴移动蛇头位置snake.insertAdjacentElement("afterbegin",tail);// 300 毫秒执行一次,检查蛇的移动方向setTimeout(move, 300);}, 300);//随机出现食物位置foodRandom();//食物随机生成 // 取值范围 0 - 290 之间 10的倍数 ,横坐标/ 纵function foodRandom() {// 0 - 290 // 0 - 29 之间 * 10 const x = Math.floor(Math.random() * 30) * 10;// y 轴 const y = Math.floor(Math.random() * 30) * 10;food.style.left = x + "px";food.style.top = y + "px";}</script>
7、游戏终止
/**
* 判断游戏是否结束
* 1. 撞墙
* 2. 撞自己
*/
js部分
<script>// 获取到蛇的domconst snake = document.getElementById("snake");// 获取到蛇的身体const snakes = snake.getElementsByTagName("div");//存储蛇的方向let dir;//创建一个变量记录按键状态let keyActive = true;// 方向的枚举值const keyArr = ["ArrowUp","ArrowDown","ArrowRight","ArrowLeft"];// 获取食物的坐标位置const food = document.getElementById("food");// 身体超过2个,不能是相反的方向const arrowDisableMap = {ArrowUp: "ArrowDown",ArrowDow: "ArrowUp",ArrowRight: "ArrowLeft",ArrowLeft: "ArrowRight",}// 通过按键事件 keydown keyup document.addEventListener("keydown",(event) => {// 通过事件对象可以获取到用的多个按键// console.log(event.keyCode);// console.log(event.key);if(keyActive && keyArr.includes(event.key)) {//console.log(snakes.length)// 获取当前方向 是否为掉头 小于2 并且不是掉头if(snakes.length < 2 || arrowDisableMap[dir] !== event.key) {dir = event.key;//更改按钮状态keyActive = false;} }});/*** 1. 禁止掉头* 2. 积分* 3. 撞墙 */// 蛇的定时移动setTimeout(function move() {//获取到蛇头let head = snakes[0];// 获取蛇头坐标let headX = head.offsetLeft;let headY = head.offsetTop;switch (dir) {case 'ArrowUp':// console.log("上")headY -= 10;break;case 'ArrowDown':// console.log("下")headY += 10;break;case 'ArrowRight'://console.log("->")headX += 10;break;case 'ArrowLeft'://console.log("左")headX -= 10;break;}//食物和蛇头是否重合if(head.offsetTop === food.offsetTop && head.offsetLeft === food.offsetLeft) {//1. 改变食物的位置foodRandom();//2. 增加蛇身体长度snake.insertAdjacentHTML("beforeend","<div/>")}/*** 判断游戏是否结束 * 1. 撞墙* 2. 撞自己*/ // 是否撞墙if(headX < 0 || headX > 290 || headY < 0 || headY > 290) {alert("撞墙了,游戏结束了!")return;}// 判断是否撞到自己的身体了 for (let i = 0; i < snakes.length - 1; i++) {if (snakes[i].offsetLeft === headX && snakes[i] === headY) {alert("撞到自己了,游戏结束了!")return;}}//移动蛇的位置,蛇的尾部const tail = snakes[snakes.length -1];tail.style.left = headX + 'px';tail.style.top = headY + 'px';// 将尾巴移动蛇头位置snake.insertAdjacentElement("afterbegin",tail);//按键归位keyActive = true;// 300 毫秒执行一次,检查蛇的移动方向setTimeout(move, 300)}, 300);//随机出现食物位置foodRandom();//食物随机生成 // 取值范围 0 - 290 之间 10的倍数 ,横坐标/ 纵function foodRandom() {// 0 - 290 // 0 - 29 之间 * 10 const x = Math.floor(Math.random() * 30) * 10;// y 轴 const y = Math.floor(Math.random() * 30) * 10;food.style.left = x + "px";food.style.top = y + "px";}</script>
8、分数和等级
我们迟到一个食物增加一份,每 5 分升一级 ,最大的等级为 27 级
js 部分
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>贪吃蛇-分数和等级</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}#main {width: 360px;height: 420px;background-color: #b7d4a8;margin: 50px auto;border-radius: 20px;border: 10px solid #000;}#snake > div {width: 10px;height: 10px;background-color: #000;position: absolute;border: 1px solid #b7d4a8;}#food {width: 10px;height: 10px;position: absolute;display: flex;flex-flow: wrap;left: 100px;top: 120px;}#food > div {height: 5px;width: 5px;background-color: #000;transform: rotate(45deg);}#stage {width: 304px;height: 304px;border: 2px solid #000;margin: 20px auto;position: relative;}#info {width: 304px;margin: 10px auto;display: flex;justify-content: space-between;font: bold 20px courier;}</style>
</head>
<body><div id="main"><!-- 舞台 --><div id="stage"><!-- 蛇 --><div id="snake"><div></div></div><!-- 食物 --><div id="food"><div></div><div></div><div></div><div></div></div></div><!-- 分数信息 --><div id="info"><div>SCORE:<span id="score">0</span></div><div>LEVEL:<span id="level">1</span></div></div></div><script>// 获取到蛇的domconst snake = document.getElementById("snake");// 获取到蛇的身体const snakes = snake.getElementsByTagName("div");//存储蛇的方向let dir;//创建一个变量记录按键状态let keyActive = true;// 方向的枚举值const keyArr = ["ArrowUp","ArrowDown","ArrowRight","ArrowLeft"];// 获取食物的坐标位置const food = document.getElementById("food");// 获取分数const scoreEl = document.getElementById("score");const levelEl = document.getElementById("level");let scoreNum = 0;let levelNum = 0;// 身体超过2个,不能是相反的方向const arrowDisableMap = {ArrowUp: "ArrowDown",ArrowDow: "ArrowUp",ArrowRight: "ArrowLeft",ArrowLeft: "ArrowRight",}// 通过按键事件 keydown keyup document.addEventListener("keydown",(event) => {// 通过事件对象可以获取到用的多个按键// console.log(event.keyCode);// console.log(event.key);if(keyActive && keyArr.includes(event.key)) {//console.log(snakes.length)// 获取当前方向 是否为掉头 小于2 并且不是掉头if(snakes.length < 2 || arrowDisableMap[dir] !== event.key) {dir = event.key;//更改按钮状态keyActive = false;} }});/*** 1. 禁止掉头* 2. 积分* 3. 撞墙 */// 蛇的定时移动setTimeout(function move() {//获取到蛇头let head = snakes[0];// 获取蛇头坐标let headX = head.offsetLeft;let headY = head.offsetTop;switch (dir) {case 'ArrowUp':// console.log("上")headY -= 10;break;case 'ArrowDown':// console.log("下")headY += 10;break;case 'ArrowRight'://console.log("->")headX += 10;break;case 'ArrowLeft'://console.log("左")headX -= 10;break;}//食物和蛇头是否重合if(head.offsetTop === food.offsetTop && head.offsetLeft === food.offsetLeft) {//1. 改变食物的位置foodRandom();//2. 增加蛇身体长度snake.insertAdjacentHTML("beforeend","<div/>");// 增加分数scoreNum ++;scoreEl.textContent = scoreNum;// 每10分增加一等级if(levelNum < 28 && scoreNum % 5 === 0) {levelNum += 1 ;levelEl.textContent = levelNum + 1;}}/*** 判断游戏是否结束 * 1. 撞墙* 2. 撞自己*/ // 是否撞墙if(headX < 0 || headX > 290 || headY < 0 || headY > 290) {alert("撞墙了,游戏结束了!,分数为:"+scoreNum)return;}// 判断是否撞到自己的身体了 for (let i = 0; i < snakes.length - 1; i++) {if (snakes[i].offsetLeft === headX && snakes[i] === headY) {alert("撞到自己了,游戏结束了!,分数为:" + scoreNum)return;}}//移动蛇的位置,蛇的尾部const tail = snakes[snakes.length -1];tail.style.left = headX + 'px';tail.style.top = headY + 'px';// 将尾巴移动蛇头位置snake.insertAdjacentElement("afterbegin",tail);//按键归位keyActive = true;// 300 毫秒执行一次,检查蛇的移动方向,最低 20 毫秒 300 - 20 = 280 setTimeout(move, 300 - levelNum * 10);}, 500);//随机出现食物位置//foodRandom();//食物随机生成 // 取值范围 0 - 290 之间 10的倍数 ,横坐标/ 纵function foodRandom() {// 0 - 290 // 0 - 29 之间 * 10 const x = Math.floor(Math.random() * 30) * 10;// y 轴 const y = Math.floor(Math.random() * 30) * 10;food.style.left = x + "px";food.style.top = y + "px";}</script></body>
</html>