仍是用的vue,原本觉得不合适,但想法错了。贪吃蛇并非经过操做dom来完成移动的,而是经过记录贪吃蛇的路径来将身体渲染出来。css
通常移动元素,咱们都是变更它的css达到目的,但我在写贪吃蛇的时候发现这样很难以实现,参考了网上的资源,发现大部分人是经过记录贪吃蛇的路径,保存进数组,经过数组变更来表示贪吃蛇的下一步,主要是增长头部位置,去除尾部位置,再动态添加css样式,这样就达到移动的效果。html
连接描述vue
<div id="snake"> <table> <tr v-for="(col,y) in cols"><td v-for="(row,x) in rows" :class="body(x,y)||showfood(x,y)?'active':''"></td></tr> </table> <button @click="start()">开始</button> </div> data(){ return{ rows:'',//横框 cols:'',//竖框 position:[[0,0],[1,0],[2,0],[3,0]],//蛇的初始位置 direction:1,//方向 food:[]//食物的位置 } },
methods:{ background(){//生成横框和竖框的函数 this.rows=Array(30) this.cols=Array(30) }, keyboard(){//键盘事件 let _this = this; document.onkeydown = function(e){ if(e.keyCode===37){ _this.change(-1) }else if(e.keyCode===38){ _this.change(-2) }else if(e.keyCode===39){ _this.change(1) }else{ _this.change(2) } } }, creatfood(){//创造食物 this.food[0]=Math.floor(Math.random()*30) this.food[1]=Math.floor(Math.random()*30) }, showfood(x,y){//显示食物 if(this.food[0]===x&&this.food[1]===y){ return true } }, body(x,y){//显示身体 for(i=0;i<this.position.length;i++){//循环身体函数,利用索引和身体位置作毕竟,若是索引和身体数组重合就会添加active样式 if(this.position[i][0]===x&&this.position[i][1]===y){ return true } } },
前期准备就是这么多,接下来就是跑起来,先声明一个计时器git
let timer=''
接着就用定时器开始跑github
start(){//开始按钮 timer=setInterval(()=>this.autorun(),300) }
这里的autorun就是咱们要写的跑动函数数组
autorun(){ let direction=this.direction//目前方向 let headX,headY// headX=this.position[this.position.length-1][0]//复制蛇头的X坐标 headY=this.position[this.position.length-1][1]//复制蛇头的Y坐标 if(direction===1||direction===-1){//若是方向是在左右跑动 direction>0?headX++:headX--//往右跑X坐标+1,往左跑X坐标-1 }else{ direction>0?headY++:headY--//若是方向是在上下跑动,Y坐标作对应处理 } //此时蛇头的下一个坐标位置就是[headX,headY],接下来就能够判断是否结束游戏,若是结束了,蛇头就不必添加了 if(headX<0||headX>29||headY<0||headY>29||this.body(headX,headY)){//当蛇头下一个位置出了边界或者这个位置是符合身体函数(即蛇头撞上了身体) alert('Game Over')//结束 clearInterval(timer)//清除定时器 this.position=[[0,0],[1,0],[2,0],[3,0]]//还原身体 this.creatfood()//从新创造食物 this.direction=1//还原方向 }else{//若是蛇头下一个位置是符合规则的 this.position.push([headX,headY])//将下一个位置添加进数组,头部长一节 if(headX!==this.food[0]||headY!==this.food[1]){//若是下一个头部位置不是食物的位置,即吃食物开始 this.position.shift()//咱们将尾部去掉,一长一短实现了蛇的走动 }else{//若是下一个头部位置是食物 this.creatfood()//不去除尾部,再次建立食物(这里有个小bug,随机的食物有概率与身体重合) } } }, change(dir){//改变方向 if(Math.abs(dir)===Math.abs(this.direction)){//若是方向相同或者想法,不作任何操做 return }else{ this.direction=dir//不然把方向改动 } },
就是这个样子,贪吃蛇就写完了,逻辑方面并非太复杂,可是对于数组的操做有不少,这里提下我遇见的几个问题:dom
let po=[[0,0],[1,0],[2,0],[3,0]] let qo=[[0,0]] let oo=[0,0] console.log(po[0]==qo[0])//false console.log(qo[0]==oo)//false
这大概就是最大的收获,我还太年轻。
由于JavaScript里面Array是对象,==或===操做符只能比较两个对象是不是同一个实例,也就是是不是同一个对象引用。目前JavaScript没有内置的操做符判断对象的内容是否相同。
可是惯性思惟让人觉得数组也是值,是能够比较的。(这段是复制的,别人总结的,和我想法如出一辙)但愿能给同为小白的朋友们提个醒函数
https://github.com/yuyeqianxu...
但愿能帮助到和我同样的小白朋友们,有bug麻烦反馈,谢谢!this