Web前端JS实现贪吃蛇 [复制链接]
发表于 2026-2-8 21:21:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
  1. <!DOCTYPE html>
  2. <html lang="zh">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Document</title>
  7.     <style>
  8.         * {
  9.             margin: 0;
  10.             padding: 0;
  11.         }
  12.         .bd {
  13.             width: 500px;
  14.             position: absolute;
  15.             transform: translateX(-50%) translateY(-50%);
  16.             left: 50%;
  17.             top: 50%
  18.         }
  19.         body {
  20.             background-color: rgba(0, 0, 0, 0.1);
  21.         }
  22.         .row {
  23.             display: flex;
  24.             justify-content: space-around;
  25.         }
  26.         span {
  27.             display: block;
  28.             width: 25px;
  29.             height: 25px;
  30.             background-color: skyblue;
  31.             /* border: 1px solid black; */
  32.         }
  33.         .bdgreen {
  34.             background-color: chartreuse;
  35.         }
  36.         .bdblack {
  37.             background-color: black;
  38.         }
  39.         .head {
  40.             background-color: coral;
  41.         }
  42.     </style>
  43. </head>
  44. <body>
  45.     <h1>当前积分</h1>
  46.     <br>
  47.     <h2></h2>
  48.     <br>
  49.     <div>使用wasd或者上下左右操作,按下esc可暂停游戏</div>
  50.     <br>
  51.     <div>
  52.         输入地图大小(输入一个正数,比如10):<br><br><input>&nbsp;<button>确认</button>
  53.     </div>
  54.     <div class="bd"></div>
  55.     <script>
  56.         // 这里修改地图大小
  57.         let base = 10;
  58.         // 这里修改蛇的前进速度
  59.         let speed = 150;
  60.         let x = 0, y = 0;
  61.         let direction = { x: 0, y: 0 }
  62.         let hassnake = []
  63.         let reward
  64.         let score = 0
  65.         let sankeLength = 1;
  66.         (function () {
  67.             if (localStorage.getItem("base") == null) {
  68.                 base = 10;
  69.                 localStorage.setItem("base", 10);
  70.             } else {
  71.                 base = Number(localStorage.getItem("base"))
  72.             }
  73.         }());
  74.         // console.log(base)
  75.         function changeBase() {
  76.             base = document.querySelector("input").value == '' ? 10 : Number(document.querySelector("input").value)
  77.             // init()
  78.             localStorage.setItem("base", base);
  79.             location.reload()
  80.         }
  81.         document.querySelector("button").addEventListener("click", () => {
  82.             changeBase()
  83.         })
  84.         document.querySelector(".bd").style.width = base * 25 + "px";
  85.         // document.querySelector(".bd").style.height = base * 20 + "px";
  86.         let arr = new Array(base)
  87.         let h = document.querySelector("h1")
  88.         const h2 = document.querySelector("h2")
  89.         localStorage.getItem("")
  90.         h2.innerHTML = `最高分数为:${localStorage.getItem("score") || 0}分`
  91.         for (let i = 0; i < arr.length; i++) {
  92.             arr[i] = new Array(base)
  93.             for (let j = 0; j < arr[i].length; j++) {
  94.                 arr[i][j] = 0
  95.             }
  96.         }
  97.         for (let i = 0; i < arr.length; i++) {
  98.             const div = document.createElement("div")
  99.             for (let j = 0; j < arr.length; j++) {
  100.                 const span = document.createElement("span")
  101.                 div.appendChild(span)
  102.             }
  103.             div.className = "row"
  104.             div.innerHTML += "<br>"
  105.             document.querySelector(".bd").appendChild(div)
  106.         }
  107.         const spanarr = document.querySelectorAll("span")
  108.         function rand() {
  109.             const x = parseInt(Math.random() * base)
  110.             const y = parseInt(Math.random() * base)
  111.             return { x, y }
  112.         }
  113.         function addReward() {
  114.             const { x, y } = rand()
  115.             spanarr[x * base + y].classList.add("bdgreen")
  116.             return { x, y }
  117.         }
  118.         function Location(x, y, lastX, lastY) {
  119.             this.x = x;
  120.             this.y = y;
  121.             this.lastX = lastX;
  122.             this.lastY = lastY;
  123.         }
  124.         function breakGame() {
  125.             alert("游戏结束")
  126.             localStorage.setItem("score", Math.max(score, localStorage.getItem("score")));
  127.             clearInterval(timer)
  128.             init()
  129.             location.reload()
  130.         }
  131.         const timer = setInterval(() => {
  132.             // 此时x和y保存上一次的位置信息
  133.             let lastX = x, lastY = y;
  134.             x += direction.x;
  135.             y += direction.y;
  136.             // console.log("当前蛇头在:", x, y)
  137.             if (x >= base || x < 0 || y >= base || y < 0) {
  138.                 breakGame()
  139.             }
  140.             // console.log("snake:")
  141.             for (let i = 0; i < sankeLength; i++) {
  142.                 for (let j = 0; j < sankeLength; j++) {
  143.                     if (i == j)
  144.                         continue;
  145.                     if (hassnake[i].x == hassnake[j].x && hassnake[i].y == hassnake[j].y) {
  146.                         breakGame()
  147.                     }
  148.                 }
  149.             }
  150.             //每一个元素都要获取前一个元素信息,
  151.             if (direction.x != 0 || direction.y != 0) {
  152.                 for (let i = sankeLength - 1; i >= 1; i--) {
  153.                     if (i == sankeLength - 1) {
  154.                         lastX = hassnake[i].x;
  155.                         lastY = hassnake[i].y
  156.                     }
  157.                     hassnake[i].x = hassnake[i - 1].x;
  158.                     hassnake[i].y = hassnake[i - 1].y;
  159.                 }
  160.                 //头部的信息
  161.                 hassnake[0].x = x;
  162.                 hassnake[0].y = y;
  163.                 hassnake[sankeLength - 1].lastX = lastX
  164.                 hassnake[sankeLength - 1].lastY = lastY
  165.             }
  166.             for (let i = 0; i < base * base; i++) {
  167.                 spanarr[i].classList.remove("bdblack")
  168.                 spanarr[i].classList.remove("head")
  169.             }
  170.             spanarr[reward.x * base + reward.y].classList.add("bdgreen")
  171.             for (let i = 0; i < sankeLength; i++) {
  172.                 spanarr[hassnake[i].x * base + hassnake[i].y].classList.add("bdblack")
  173.             }
  174.             spanarr[hassnake[0].x * base + hassnake[0].y].classList.remove("bdblack");
  175.             spanarr[hassnake[0].x * base + hassnake[0].y].classList.add("head");
  176.             if (x == reward.x && y == reward.y) {
  177.                 spanarr[x * base + y].classList.remove("bdgreen")
  178.                 reward = addReward()
  179.                 const Controls = new Location(hassnake[sankeLength - 1].lastX, hassnake[sankeLength - 1].lastY, 0, 0)
  180.                 hassnake.push(Controls)
  181.                 score += 1
  182.                 h.innerHTML = `当前积分:${score}`
  183.                 sankeLength += 1
  184.             }
  185.         }, speed)
  186.         function init() {
  187.             reward = addReward()
  188.             spanarr[0].classList.add("bdblack")
  189.             direction = { x: 0, y: 0 }
  190.             his = []
  191.             score = 0
  192.             sankeLength = 1
  193.             h.innerHTML = `当前积分:${score}分`
  194.             hassnake = []
  195.             const init = new Location(0, 0, 0, 0)
  196.             hassnake.push(init)
  197.         }
  198.         init()
  199.         window.addEventListener("keyup", function (e) {
  200.             console.log(e)
  201.             if (e.code == "KeyW" || e.code == "ArrowUp") {
  202.                 direction = { x: -1, y: 0 }
  203.             }
  204.             if (e.code == "KeyD" || e.code == "ArrowRight") {
  205.                 direction = { x: 0, y: 1 }
  206.             }
  207.             if (e.code == "KeyS" || e.code == "ArrowDown") {
  208.                 direction = { x: 1, y: 0 }
  209.             }
  210.             if (e.code == "KeyA" || e.code == "ArrowLeft") {
  211.                 direction = { x: 0, y: -1 }
  212.             }
  213.             if (e.code == "Escape") {
  214.                 direction = { x: 0, y: 0 }
  215.             }
  216.             if (e.code == "Enter") {
  217.                 changeBase()
  218.             }
  219.         })
  220.     </script>
  221. </body>
  222. </html>
复制代码
学js的时间突然发现贪吃蛇好像就是生存到一个二维数组,然后根据差别的状态渲染页面就行,于是利市写出来了,不外感觉时间复杂度有点高,应该有更好的实现方式(每一次移动只须要按照方向添加一个玄色方块然后去掉末了一个玄色方块就行,如果吃到了绿色方块就不须要去掉末了一个玄色方法),只要能跑就行了
调解移动速率可以修改speed(单元是毫秒),直接用speed做定时器的循环时间
没有写绿色方块不能天生在玄色方块的逻辑(只要循环一下玄色方块,然后判定一下随机数在不在内里,在内里就重新天生一个,直到没有)
看起来应该没有BUG吧......


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表