贪吃蛇游戏

89 阅读1分钟
 <!-- 写个带注释的版本 -->
 <!DOCTYPE html>
 <html lang="en">
 ​
 <head>
   <meta charset="UTF-8" />
   <meta http-equiv="X-UA-Compatible" content="IE=edge" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <title>Document</title>
   <style>
     .root {
       display: flex;
       flex-wrap: wrap;
       border: 1px #ddd solid;
     }
 ​
     .player {
       background: grey;
     }
 ​
     .item {
       box-sizing: border-box;
       border: 1px #ddd solid;
     }
 ​
     .food {
       background-color: orange;
     }
   </style>
 </head>
 ​
 <body>
   <div class="root"></div>
 ​
   <script>
     let size = 20,
       n = 10;
     let table = [],
       res = [];
     let player = [[1, 1]];
 ​
     let root = document.querySelector(".root");
     //1. 样式渲染
     for (let i = 0; i < n; i++) {
       for (let j = 0; j < n; j++) {
         const isEat = Math.random() > 0.9 ? true : false;
         table.push(
           `<div class = "item ${isEat ? "food" : ""
           }" data-v=_${i}-${j}  style="width:${size}px;height:${size}px"}></div>`
         );
       }
     }
 ​
     //1. 根据 player 坐标,渲染节点
     const update = function () {
       //清除player
       document
         .querySelectorAll(".player")
         .forEach((item) => item.classList.remove(".player"));
       player.forEach((item) => {
         const local = item.join("-"); //坐标拼接
         document.querySelector(`[data-v=_${local}]`).classList.add("player"); //渲染
       });
     };
     root.innerHTML = table.join("");//表格渲染在此
     root.style.width = `${size * n}px`;
     root.style.height = `${size * n}px`;
     let key = ""; // 获得键位
     document.addEventListener("keydown", (e) => {
       key = e.key;
     });
     //贪吃蛇自动运动
     const time1 = setInterval(() => {
       if (key) {
         const tmp1 = player.slice(0, player.length - 1);//获得当前坐标
         console.log(tmp1);
         const tmp = JSON.parse(JSON.stringify(tmp1));//tmp保存当前坐标
         // player[ [行坐标,列坐标 ] ] ,根据键位修改坐标
         switch (key) {
           case "w":
             player[0][0] -= 1;
             break;
           case "s":
             player[0][0] += 1;
             break;
           case "a":
             player[0][1] -= 1;
             break;
           case "d":
             player[0][1] += 1;
             break;
         }
         const newHead = player[0].join("-"); //新的头部坐标
         const judge = document.querySelector(`div[data-v=_${newHead}]`); //新的头部是否越界了
         if (!judge) {
           //越界直接结束
           clearInterval(time1);
           alert("Out"); //结束
         } else {
           //否则,把保存的加进来
           for (let i = 1; i < player.length; i++) {
             player[i] = tmp[i - 1];
           }
           //如果这一格是个食物,那么就加入到 player 里面
           if (judge.className.indexOf("food") >= 0) {
             judge.classList.remove("food");
             player.push([...player[0]]);
           }
           update(); //渲染节点
         }
       }
     }, 500);
     update(); //执行函数,首次渲染的头结点在此
   </script>
 </body>
 ​
 </html>