实现效果 1、CSS文件 base.css文件
html ,body{/*逗号表示并集选择器*/ width: 100%; } .map{ width: 90px; height: 90px; margin: 50px auto; background-color:#ccc; } .map ul{ height: 30px; } .map ul li{ width: 28px; height: 28px; border: 1px solid #af0; float: left; } .map ul li.snake{ /*交集选择器*/ background-color: blue; } .map ul li.egg{ background-color: crimson; }reset.css文件
* { /*去掉所有标签的内外边距*/ padding:0; margin:0; } ul{ list-style: none; }2、JS文件 msk.js
// 1.0 获取相关元素 var box = document.querySelector(".msk"); var tips = document.querySelector(".tips"); var restartBtn = document.querySelector(".restart_btn"); var quxiaoBtn = document.querySelector(".quxiao_btn"); // 2.0 封装一个方法 function show(str , callback){ // 2.0.1 显示msk盒子 box.style.display = "block"; // 2.0.2 设置提示语 tips.innerHTML = str; // 2.0.3 再玩一次 restartBtn.onclick = function(){ // 2.0.6 隐藏msk盒子 box.style.display = "none"; // 2.0.4 if(callback){ //判断是否存在回调函数 callback();//是 调用 } } // 2.0.5 隐藏msk盒子 quxiaoBtn.onclick = function(){ // 2.0.6 隐藏msk盒子 box.style.display = "none"; } }snake.js
/* //console.log("text") //定义变量 //获取.map这个标签 var ele = document.querySelector('.map'); var resultEle = document.querySelector(".result span") //定义多少行多少列 var rowCount = 15; var colCount = 15; //定义列的大小 var space = 30; //设置map的宽度和高度 ele.style.width = colCount * space + "px"; ele.style.height = rowCount * space + "px"; //定义一个 数组,记录所有的li标签 var ali = []; //循环 创建ul标签,没循环一次,创建一个标签 for (var i = 0; i < rowCount; i++) { var ulCreate = document.createElement("ul"); //定义小数组,记录每一行有多少个标签 var rowArr = []; //循环创建li标签 for (var j = 0; j < colCount; j++) { //没循环一次,创建一个li标签 var liCreate = document.createElement("li"); //往数组(小)里面,添加一个li rowArr.push(liCreate); ulCreate.appendChild(liCreate); } //往map标签(ele)添加ulCreate标签 ele.appendChild(ulCreate); //把小数组添加到大数组里面去 ali.push(rowArr); } //绘制蛇(代表蛇的li标签,类名snake) //定义数组 console.log(ali) var snakeBody = []; for (var k = 0; k < 3; k++) { ali[0][k].className = "snake"; snakeBody.push(ali[0][k]); } //绘制食物 console.log(snakeBody) var eggX = 0; var eggY = 0; //产生随机数的函数 function rd(max, min) { //产生0-10之间的随机数,带小数点 //产生指定范围的随机数,带小数点 return Math.floor(Math.random() * (max - min) + min); //Math.random()*10 } //产生食物的坐标 function createFood() { eggX = rd(colCount - 1, 0); //创建行 eggY = rd(rowCount - 1, 0); if (ali[eggY][eggX].className == "snake") { createFood(); } else { ali[eggY][eggX].className = "egg"; } } createFood(); //分数的变量 //1、控制蛇的移动方向 蛇移动的坐标(默认) var x = 2; var y = 0; //2、移动方向 var direction = "right"; //3、boolean var isChange = false; //4、定时器函数 var timer = setInterval(move, 200); //5、编写移动的逻辑 function move() { //控制流语句 switch (direction) { //向右边 case "right": x++; break; case "left": x--; break; case "down": y++; break; case "up": y--; break; } //判断蛇移动的范围 if (x < 0 || x > (colCount - 1) || y < 0 || y > (rowCount - 1)) { //提示 alert("游戏结束!") //停止定时器函数 clearInterval(timer) return; } //判断蛇吃到食物的时候 if (eggX == x && eggY == y) { //设置食物的背景色 ali[eggY][eggX].className = "snake"; //把食物的标签添加到snakebody snakeBody.push(ali[eggY][eggX]); createFood(); //加分 score = score + 1; //显示分数 resultEle.innerHTML = score; } else { //设置蛇数组的第一个元素的类名 snakeBody[0].className = ""; //删除蛇数组的第一个元素 snakeBody.shift(); //添加下一个元素 snakeBody.push(ali[y][x]); //给下一个元素设置类名 ali[y][x].className = "snake"; } //ali[y][x].className = "snake"; } //通过键盘事件改变 document.onkeydown = function (evt) { //防止连续快速按键 if (isChange) { return; } //如果蛇正朝着,右边走,按左边键盘无效 var code = evt.keyCode; if (direction == "right" && code == 37) { return; } if (direction == "left" && code == 39) { return; } if (direction == "down" && code == 38) { return; } if (direction == "up" && code == 40) { return;//终止代码 } switch (code) { case 40: direction = "down"; isChange = true; break; case 38: direction = "up"; isChange = true; break; case 39: direction = "right"; isChange = true; break; case 37: direction = "left"; isChange = true; break; } //延迟200ms setTimeout(function () { isChange = false; }, 200) } */ //console.log("test")// 检查代码 // 1.0 定义变量 // 1.0.1 获取.map这个标签 var ele = document.querySelector('.map'); var resultEle = document.querySelector(".result span"); // 1.0.2 定义多少行 var rowCount = 15; // 2.0.3 定义多少列 var colCount = 15; // 2.0.4 定义列的大小 var space = 30; // 2.0.5 设置map的宽度高度 ele.style.width = colCount * space + "px"; ele.style.height = rowCount * space + "px"; // 3.0 定义数组(大)记录所有的li标签 var aLi = []; // 4.0 循环 创建ul标签(行) for(var i = 0 ; i < rowCount; i++){ // 4.0.1每循环一次 创建一个ul标签 var ulCreate = document.createElement("ul") // 4.0.2定义数组(小)记录每一行有多少个li标签 var rowArr = []; // 4.0.3循环 创建li标签(列) for(var j = 0 ; j < colCount ; j++){ //4.0.4 每循环一次 创建一个li标签 var liCreate = document.createElement("li"); //4.0.5往数组(小)添加li标签 rowArr.push(liCreate) //4.0.6往ulCreate标签 添加li标签 ulCreate.appendChild(liCreate); } // 4.0.7往map标签(ele)添加ulCreate标签 ele.appendChild(ulCreate); // 4.0.8 把小数组(rowArr) 添加到大数组(aLi) aLi.push(rowArr); } console.log(aLi) // 5.0 绘制蛇(代表蛇的li标签 类名 snake) // 5.0.1 定义数组(蛇) var snakeBody = []; // 5.0.2 默认第一行前三个li标签为蛇 for(var k = 0 ; k < 3 ; k++){ // 5.0.3 设置第一行前三个li标签 添加类名 snake aLi[0][k].className = "snake"; // 5.0.4 往蛇数组添加 第一行前三个li标签 snakeBody.push( aLi[0][k]); } console.log(snakeBody) // 6.0 绘制食物 // 6.0.1 定义食物的x坐标 var eggX = 0; var eggY = 0; // 6.0.2 产生随机数的函数 function rd(max , min){ // 6.0.3 处理随机数的逻辑 // Math.random()*10 产生0-10之间随机数 带小数点 // Math.random()*10 + 10 产生10-20之间随机数 带小数点 // Math.random()*(max - min) + min ; 产生指定范围的随机数 带小数点 // Math.floor(); 向下取整 1.123123 => 1 return Math.floor(Math.random()*(max-min)+min); } // 6.0.3 产生食物的坐标 function createFood(){ // 6.0.4 创建 列 x colCount eggX = rd(colCount-1,0); // 6.0.5 创建 行 y rowCount eggY = rd(rowCount-1,0); // 6.0.6 判断创建的坐标对应的li标签 是否带有 snake 类名 if(aLi[eggY][eggX].className == "snake"){ // 6.0.7 重新创建食物 createFood(); }else { // 6.0.7 设置食物的类名 egg aLi[eggY][eggX].className = "egg"; } } // 6.0.8 调用创建食物的函数 createFood(); // 9.0 定义分数的变量 var score = 0; // 7.0 控制蛇移动的方向 // 7.0.1 蛇移动的x坐标 和 y 坐标 (默认) var x = 2; var y = 0; // 7.0.2 移动方向 var direction = "right"; // 7.0.3 布尔值 var isChange = false; // 7.0.4 定时器函数 var timer = setInterval(move, 200);//1000毫秒 = 1秒 // 7.0.5 编写移动的逻辑 function move(){ // 7.0.6 控制流语句 switch(direction){ case "right": // 向右 x++; break ; case "left": // 向左 x--; break ; case "down": // 向下 y++; break; case "up": // 向上 y--; break; } // 7.0.6.1 判断蛇移动的范围 if(x < 0 || x > (colCount-1) || y < 0 ||y > (rowCount-1)){ //alert("游戏结束! ");//提示 // 7.0.6.2 调用show方法 show("游戏结束! " ,function(){ // 7.0.6.3 分数重新计算 score = 0; // 7.0.6.4 继续游戏(-) // timer = setInterval(move,200); // 刷新页面 继续游戏 window.location.reload(); }) clearInterval(timer)//停止定时器函数 return ; //终止代码 } // 7.0.8 判断蛇吃到食物的时候 if(eggX == x && eggY == y){ // 7.0.9 设置食物的背景色 aLi[eggY][eggX].className = "snake"; // 7.0.10 把食物的标签添加到 snakeBody snakeBody.push(aLi[eggY][eggX]); // 7.0.11 重新创建食物 createFood(); // 7.0.12 记录分数 // score+=1; score = score + 1; // 7.0.17 显示分数 resultEle.innerHTML = score; }else { // 7.0.13 设置蛇数组的第一个元素类名 snakeBody[0].className = ""; // 7.0.14 删除蛇数组第一个元素 snakeBody.shift(); // 7.0.15 添加下一个元素 snakeBody.push(aLi[y][x]); // 7.0.16 给下一个元素设置类名 aLi[y][x].className = "snake"; } // 测试 // aLi[y][x].className = "snake"; } // 8.0 通过键盘事件改变 direction 的值 document.onkeydown = function(evt){ // 8.0.4 防止连续快速按键 if(isChange){ return;//终止代码 } // 8.0.1 键值码 var code = evt.keyCode; // 8.0.3 移动的方向处理 // 如果蛇正朝着 右边走 ,按左边按键无效 if(direction == "right" && code == 37){ return ;//终止代码 } if(direction == "left" && code == 39){ return ;//终止代码 } if(direction == "down" && code == 38){ return ;//终止代码 } if(direction == "up" && code == 40){ return ;//终止代码 } // 8.0.2 根据keyCode 改变 direction switch(code){ case 40 : direction = "down"; isChange = true; break; case 38 : direction = "up"; isChange = true; break; case 39 : direction = "right"; isChange = true; break; case 37 : direction = "left"; isChange = true; break; } // 8.0.5 延迟200毫秒 setTimeout(function(){ isChange = false; },200) // 10. 拓展暂停(空格按键) 开始(S按键) // 暂停(空格按键)32 console.log(code) if(code == 32) { // 停止执行定时器函数 clearInterval(timer); return; } // 开始(S按键) if(code == 83){ // 停止执行定时器函数(用定时器 , 先清除定时器) clearInterval(timer); // 继续执行定时器函数(继续游戏) timer = setInterval(move , 200); } }3、HTML文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>蛇和蛋蛋的故事</title> <!-- 引入样式文件 --> <link rel="stylesheet" href="css/reset.css"> <link rel="stylesheet" href="css/base.css"> <style> .result { width: 150px; height: 40px; background-color: #ccc; line-height: 40px; color: #fff; position: fixed; left: 0; bottom: 50px; z-index: 1000; } .result span { color: red; } .msk { width: 220px; height: 120px; background-color: #fff; border: 1px solid #ccc; /* 定位 */ position: absolute; left: 50%; top: 50%; margin-left: -110px; margin-top: -60px; /* 内边距 */ padding: 0 10px; /* 隐藏盒子 */ display: none; } .msk p { width: 220px; height: 50px; line-height: 50px; text-align: center; } .msk p span { color: #666; } .msk .btn { height: 36px; line-height: 36px; text-align: center; cursor: pointer; padding: 0 15px; border-radius: 5px; font-size: 13px; margin-top: 20px; } .restart_btn { float: left; color: skyblue; border: 1px solid skyblue; } .quxiao_btn { float: left; color: red; border: 1px solid red; margin-left: 10px; } </style> </head> <body> <!-- 显示分数 --> <div class="result">当前分数 : <span>0</span> </div> <!-- 地图 --> <div class="map"> <!-- 动态创建 --> </div> <!-- 弹窗 --> <div class="msk"> <p><span class="tips"> xxx </span></p> <div class="btn restart_btn">再玩一次</div> <div class="btn quxiao_btn">取消</div> </div> </body> </html> <!-- 遮罩层 --> <script src="js/msk.js"></script> <!-- 贪吃蛇 --> <script src="js/snake.js"></script>