JavaScript贪吃蛇的实现代码
本文实例为大家分享了JavaScript实现贪吃蛇的具体代码,供大家参考,具体内容如下
首先我们要确定贪吃蛇应有的功能
1.通过键盘的上下左右控制蛇的移动方向
2.边界判定,即蛇头超出边界则游戏结束
3.碰撞判定,即蛇头和食物块发生触碰
4.吃到食物积分加1
具体实现
一.html代码
<div class="container"> <!--小蛇移动的操场--> <div id="playground"> <!--小蛇--> <div id="snake"></div> <!--食物--> <div id="food"></div> </div> <!--记录得分--> <div id="menu"> <div>得分<span id="score"></span></div> </div> </div>
二.css代码
<style> * { padding: 0; margin: 0; } .container { width: 800px; height: 600px; margin: 0 auto; } #playground { width: 650px; height: 100%; background-color: cadetblue; float: left; position: relative; } #menu { width: 150px; height: 100%; background-color: darkcyan; float: left; } #snake { width: 20px; height: 20px; background-color: #d3e0d7; position: absolute; left: 0; top: 0; } #food { width: 20px; height: 20px; background-color: #027766; position: absolute; } .body { width: 20px; height: 20px; background-color: #178b9a; position: absolute; ; top: 0; left: 0; } #score { font-size: 30px; font-weight: bold; color: black; } #menu div { font-size: 20px; font-weight: bold; margin-left: 20px; } #hqx { width: 100px; height: 50px; margin: 0 auto; } #inp { border: 0; width: 100px; height: 50px; background-color: coral; } </style>
三.开始实现具体功能
1.先获取节点,设置全局变量
//获取节点 var snake = document.getElementById("snake"); var food = document.getElementById("food"); var playground = document.getElementById("playground"); var score = document.getElementById('score'); // var inp = document.getElementById('inp') /*设置全局变量*/ var timer; var arr = []; //存放蛇的位置的数组 var num = 0; //数组的长度 var snakeBody; //每次吃调一个食物,增加的身体
2.设置按键事件,并判断边界碰撞,碰撞时游戏结束。这一块代码我遇到了一个问题,就是当我用if(){return}跳出事件,会结束所有代码,后面的代码就不会执行了,然后我换成了switch(){ case: break;}就实现效果了
//设置按键事件 document.onkeydown = function (e) { var evt = window.evnet || e; switch (evt.keyCode) { case 37: //左 clearInterval(timer); timer = window.setInterval(runLeft, 10); //向左移动的时间器 function runLeft() { if (snake.offsetLeft > 0) { snake.style.left = snake.offsetLeft - 1 + 'px'; //实现自己动 snake.style.top = snake.offsetTop + 'px'; //高度不变 arr.push([snake.offsetLeft, snake.offsetTop]); //每移动1px,就将位置存进数组中 num++; //相应的数组长度加1 } else { clearInterval(timer); //清除定时器 alert('you die') //弹出失败信息 document.onkeydown = null //结束按键 } } break; //结束当前按键 case 38: //上 clearInterval(timer); timer = window.setInterval(runTop, 10); function runTop() { if (snake.offsetTop > 0) { snake.style.top = snake.offsetTop - 1 + 'px'; snake.style.left = snake.offsetLeft + 'px'; arr.push([snake.offsetLeft, snake.offsetTop]); num++; } else { clearInterval(timer); alert('you die') document.onkeydown = null } } break; case 39: //右 clearInterval(timer); timer = window.setInterval(runRight, 10); function runRight() { if (snake.offsetLeft < 630) { snake.style.left = snake.offsetLeft + 1 + 'px'; snake.style.top = snake.offsetTop + 'px'; arr.push([snake.offsetLeft, snake.offsetTop]); num++; } else { clearInterval(timer); alert('you die') document.onkeydown = null } } break; case 40: //下 clearInterval(timer); timer = window.setInterval(runBottom, 10); function runBottom() { if (snake.offsetTop < 580) { snake.style.top = snake.offsetTop + 1 + 'px'; snake.style.left = snake.offsetLeft + 'px'; arr.push([snake.offsetLeft, snake.offsetTop]); num++; } else { clearInterval(timer); alert('you die') document.onkeydown = null } } break; }
3.封装一个函数,随机生成食物位置,第一次粗心忘记加单位,看网页没效果,才知道忘记加单位了
function pos() { food.style.left = parseInt(Math.random() * 630) + 'px'; food.style.top = parseInt(Math.random() * 580) + 'px'; }
4.封装一个碰撞判定函数,使其碰撞时,食物消失,蛇的身体增加一块。这里遇到一个定时器问题,第一次写的时候,我的定时器清除标识和之前的定时器标识一致,导致蛇会上下左右抖动,经过后面不停的修改,最终找到错误。
var timer1 = setInterval(eat, 10); //设置一个碰撞的时间器 function eat() { snakeCrashFood(snake, food); //传入参数 function snakeCrashFood(obj1, obj2) { var obj1Left = obj1.offsetLeft; var obj1Width = obj1.offsetWidth + obj1.offsetLeft; var obj1Top = obj1.offsetTop; var obj1Height = obj1.offsetHeight + obj1.offsetTop; var obj2Left = obj2.offsetLeft; var obj2Width = obj2.offsetWidth + obj2.offsetLeft; var obj2Top = obj2.offsetTop; var obj2Height = obj2.offsetHeight + obj2.offsetTop; if (!((obj1Width < obj2Left) || (obj2Width < obj1Left) || (obj1Height < obj2Top) || ( obj2Height < obj1Top))) { snakeBody = document.createElement("div"); //生成新的div snakeBody.setAttribute("class", "body"); //给新的div添加类名 playground.appendChild(snakeBody); //添加一节新的身体 pos(); //让食物重新随机出现 setInterval(follow, 10); //动态地改变新的身体的位置 } } }
5.设置蛇的身体跟随,获得蛇身体的数组,新的身体相对于上一个身体的第20个数组的位置。这里我遇到了一个数组越界问题。最开始初始num值为0,place=20,所以第一次身体的增加arr[num-place][0]前面的索引是从负数开始,在通过老师的指导,增加一个判定,解决了这个问题。
function follow() { /*获得增加的身体的数组*/ var bodyNum = document.getElementsByClassName("body"); score.innerHTML = bodyNum.length; var place = 0; /*数组每移动1px,新的身体的位置就是相对于前一个身体的第20个数组的位置,后面依次加等*/ // console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1") // console.log("arr : ==" + arr) // console.log("num : ==" + num) //2 for (var i = 0; i < bodyNum.length; i++) { // console.log("bodyNum.length : ==" + bodyNum.length) place += 20; // console.log("place : ==" + place)//20 // console.log("num - place : ==" + (num - place))//-18 // bodyNum[i].style.left = arr[num - place][0] + 'px'; // bodyNum[i].style.top = arr[num - place][1] + 'px'; if (num - place > 0) { bodyNum[i].style.left = arr[num - place][0] + 'px'; bodyNum[i].style.top = arr[num - place][1] + 'px'; } } // console.log("num555 : ==" + num) // console.log("===========================================") }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
springMVC + easyui + $.ajaxFileUpload实现文件上传注意事项
在使用easyUI做前端样式展示时,遇到了文件上传的问题,而且是在弹出层中提交表单,想做到不刷新页面,所以选择了使用ajaxFileUpload插件。下面通过本文给大家分享springMVC + easyui + $.ajaxFileUpload实现文件上传注意事项,需要的朋友参考下吧2017-04-04实例分析Array.from(arr)与[...arr]到底有何不同
这篇文章通过实例主要给大家分析介绍了关于Array.from(arr)与[...arr]到底有何不同的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用js具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧2019-04-04javascript自定义startWith()和endWith()的两种方法
js中自定义startWith()和endWith()方法有两种,在本文将为大家详细介绍下,感兴趣的朋友不要错过2013-11-11
最新评论