,一行js代码。小游戏已经成为最高级别的伪装!代码如下:(function(){vars=[41,40],d=1,f=43,x,c=document.createElement('canvas');c.width=400;c.height=400;c.style.background="#535353";c.textContent="当前浏览器不支持canvas标签";b=c.getContext('2d');functionw(s,c){b.fillStyle=c;b.fillRect(s%20*20,~~(s/20)*20,18,18);};document.onkeydown=function(e){d=s[1]-s[0]==(x=[-1,-20,1,20][(e||event).keyCode-37]||d)?d:x;};!(function(){s.unshift(x=s[0]+d);如果(s.indexOf(x,1)>0||x<0||x>399||d==1&&x%20==0||d==-1&&x%20==19)returnalert('Gameover!');w(x,'#2396ef');x===f?(()=>{while(s.indexOf(f=~~(Math.random()*399))>0);w(f,'#35e3dc');})():w(s.pop(),'#535353');setTimeout(参数。callee,300);})();document.body.appendChild(c);})();ps:我不是来装的。!好了,我们运行这行代码,看看效果:看动画是不是很好玩?,OK,可以去网上看看demo可以撒,具体例子。伪装完成了。好了,言归正传,我怎么会来装逼,我要分析一下这是怎么玩的,这就是我的目的。我们拆分代码来看:首先最外层包裹了一个自调用函数,如下:(function(){//具体内容})();//自调用函数当然不止这种方式写完再进行第二步,绘制场景,很明显要使用HTML5的canvas标签,我们可以使用document.createElement()方法创建元素,继续:(function(){//createcanvastagvarc=document.createElement('canvas');})();蛇运动的场景必须是固定尺寸的,也就是说我们需要设置画布的宽高,这里我设置的是400X400,然后给场景添加背景。就是这样:(function(){//创建画布标签varc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';})();canvas元素创建好了,我们要将它添加到DOM页面中,所以使用appendChild()来添加它。如下:(function(){//创建画布标签varc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';document.正文.appendChild(c);})();哦,有些浏览器可能不支持canvas标签,所以我们不能忘记给出一个优雅的提示:(function(){//createcanvastagvarc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';c.textContent="当前浏览器不支持canvas标签";document.body.appendChild(c);})();场景被绘制。接下来,我们需要在场景中画一条蛇,因此canvas.getContext('2d')这个方法必不可少。(function(){//创建画布标签varc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';varb=c.getContext('2d');document.body.appendChild(c);})();接下来分析蛇的成分。其实这里的场景可以看做是20*20的400块。那么snake也可以看作是一个块一个块地合成。用专业术语来说,就是一个队列,也就是一个数组,[20]。这里,蛇被初始化为2个块,即[20,20]。然后蛇的初始位置要稍微调整一下,所以改为[40,40]。其实这里刚出现的时候是隐藏的如果吃了一块食物默认会在蛇初始位置的下一个格子,然后蛇会马上吃掉它,然后是下一个食物位置会随机出现,所以默认food位置是40,为了方便的小差异,稍微增加到43。那么,现在我们需要知道蛇跑的方向。蛇可以上下左右移动。然后,我们定义为s[1]-s[0],根据位置计算。我们先定义蛇:(function(){//创建画布标签varc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';varb=c.getContext('2d');vars=[41,40],//这里41也有讲究d=1,//定义蛇的活动方向,默认向右f=42;//默认食物的位置document.body.appendChild(c);})();接下来开始画蛇,蛇的活动轨迹和食物。定义一个函数,用canvas.fillStyle()填充背景,其中蛇、食物、蛇活动轨迹都是一个小方矩形,所以我们用canvas.fillRect()画一个矩形。该方法中有四个参数,如下图所示:蛇活动的轨迹坐标,即定义的蛇数组的坐标,所以第一个参数为s%20*20,第二个参数为~~(s/20*20)。关于~~运算符,不理解的可以看我的JavaScript位运算符一文。这里感觉有点抽象。其实需要靠自己的想象力去想象和理解。(function(){//创建画布标签varc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';varb=c.getContext('2d');vars=[41,40],//这里的41也是有讲究的,表示默认右方向d=1,//定义蛇的活动方向,默认是向右,和蛇的运动方向为s[1]-s[0]f=42;//默认食物的位置//这个函数不仅要画蛇方块,还要画食物和定义的蛇活动轨迹函数w(s,c){b.fillStyle=c;b.fillRect(s%20*20,~~(s/20*20),18,18);}document.body.appendChild(c);})();向数组中添加一个20*20的小块。当然,为了区分方向,这里小块的宽高应该和绘制矩形的宽高相关。因此,我们还需要定义一个变量来表示蛇吃完食物后随机出现的下一个食物的位置。(function(){//创建画布标签varc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';varb=c.getContext('2d');vars=[41,40],//这里的41也是有讲究的,表示默认右方向d=1,//定义蛇的活动方向,默认是向右,和thesnake'smovementdirectioniss[1]-s[0]f=42,//默认的食物位置x;//这个函数不仅仅是画蛇方块,还要画出食物和蛇活动的定义轨迹函数w(s,c){b.fillStyle=c;b.fillRect(s%20*20,~~(s/20*20),18,18);}document.body.appendChild(c);})();接下来就是用户按下键盘键的方向,当然也可以是wsad字母键来控制snake活动的方向。但是,我们需要知道键盘按键的keyCode。方向键的keyCode分别是:left:37,up:38,right:39,down:40。键盘事件是onkeydown。(function(){//创建画布标签varc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';varb=c.getContext('2d');vars=[41,40],//这里的41也是有讲究的,表示默认右方向d=1,//定义蛇的活动方向,默认是向右,和thesnake'smovementdirectioniss[1]-s[0]f=42,//默认的食物位置x;//这个函数不仅仅是画蛇方块,还要画出食物和蛇活动的定义trajectoryfunctionw(s,c){b.fillStyle=c;b.fillRect(s%20*20,~~(s/20*20),18,18);}//按方向键控制snake的移动方向,这里根据食物的位置来控制方向,防止用户随意改变方向,导致游戏崩溃document.onkeydown=function(e){d=s[1]-s[0]===(x=[-1,-20,1,20][e||event].keyCode-37]||d)?d:x;}document.body.appendChild(c);})();然后蛇在吃完一种食物后要添加下一种食物,这里使用unshift()方法添加数组。(function(){//创建画布标签varc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';varb=c.getContext('2d');vars=[41,40],//这里的41也是有讲究的,表示默认右方向d=1,//定义蛇的活动方向,默认是向右,和thesnake'smovementdirectioniss[1]-s[0]f=42,//默认的食物位置x;//这个函数不仅仅是画蛇方块,还要画出食物和蛇活动的定义trajectoryfunctionw(s,c){b.fillStyle=c;b.fillRect(s%20*20,~~(s/20*20),18,18);}//按方向键控制蛇的移动方向,这里根据食物的位置来控制方向,防止用户随意改变方向,导致游戏崩溃document.onkeydown=function(e){//方向由蛇头决定,最初的蛇只由2个小方块组成,所以方向蛇是s[1]-s[0]d=s[1]-s[0]===(x=[-1,-20,1,20][e||事件].keyCode-37]||d)?d:x;}!(function(){s.unshift(x=s[0]+d);})();//这也是一个自调用函数document.body.appendChild(c);})();接下来判断蛇是撞到墙上还是撞到自己,游戏结束。(function(){//创建画布标签varc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';varb=c.getContext('2d');vars=[41,40],//这里的41也是有讲究的,表示默认右方向d=1,//定义蛇的活动方向,默认是向右,和thesnake'smovementdirectioniss[1]-s[0]f=42,//默认的食物位置x;//这个函数不仅仅是画蛇方块,还要画出食物和蛇活动的定义trajectoryfunctionw(s,c){b.fillStyle=c;b.fillRect(s%20*20,~~(s/20*20),18,18);}//按方向键控制蛇的移动方向,这里根据食物的位置来控制方向,防止用户随意改变方向,导致游戏崩溃document.onkeydown=function(e){//方向由蛇头决定,最初的蛇只由2个小方块组成,所以蛇的方向是s[1]-s[0]d=s[1]-s[0]===(x=[-1,-20,1,20][e||事件].keyCode-37]||d)?d:x;}!(function(){s.unshift(x=s[0]+d);//判断蛇是撞墙还是自己,游戏结束if(s.indexOf(x,1)>0||x<0||x>399||d==1&&x%20==0||d==-1&&x%20==19)returnalert('gameover');})();//这也是一个自动调用函数document.body.appendChild(c);})();然后开始绘制食物,判断食物是否被蛇吃掉,如果被吃掉,则随机生成下一个食物(function(){//创建画布标签varc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';varb=c.getContext('2d');vars=[41,40],//这里的41也是有讲究的,表示默认右方向d=1,//定义蛇的活动方向,默认是向右,和thesnake'smovementdirectioniss[1]-s[0]f=42,//默认的食物位置x;//这个函数不仅仅是画蛇方块,还要画出食物和蛇活动的定义trajectoryfunctionw(s,c){b.fillStyle=c;b.fillRect(s%20*20,~~(s/20*20),18,18);}//按方向键控制蛇的移动方向,这里根据食物的位置来控制方向,防止用户随意改变方向,导致游戏崩溃document.onkeydown=function(e){//方向由蛇头决定,最初的蛇只由2个小方块组成,所以方向蛇是s[1]-s[0]d=s[1]-s[0]===(x=[-1,-20,1,20][e||事件].keyCode-37]||d)?d:x;}!(function(){s.unshift(x=s[0]+d);//判断蛇是撞墙还是自己,游戏结束if(s.indexOf(x,1)>0||x<0||x>399||d==1&&x%20==0||d==-1&&x%20==19)returnalert('gameover');//然后开始绘制蛇节点的颜色w(x,'#e641d3');//判断蛇是否吃过食物,如果吃过,则随机生成一个新节点,该节点为新食物所在的位置标准的,Math.random()方法的意思是取一个随机数,因为方向可能是负数,所以用~~符号表示取绝对值取正数。~表示先取反再减一。如果(x==f){而(s.indexOf(f=~~(Math.random()*399))>0);//重绘食用色素w(f,'#35e3dc');}else{//snakeeat到食物时,蛇的身体会变长,所以不会改变蛇的运动轨迹w(s.pop(),'#535353');}})();//这也是一个自调用函数document.body.appendChild(c);})();最后让蛇跑一定时间,如下:(function(){//创建画布标签varc=document.createElement('canvas');c.width=400;c.height=400;c.style.background='#535353';varb=c.getContext('2d');vars=[41,40],//这里41也有讲究,代表默认的Rightwarddirectiond=1,//定义蛇的活动方向,默认是向右,蛇的运动方向是s[1]-s[0]f=42,//默认的食物位置x;//这个函数是绘制snake块也是绘制食物和蛇活动轨迹函数的定义w(s,c){b.fillStyle=c;b.fillRect(s%20*20,~~(s/20*20),18,18);}//按方向键控制小蛇的移动方向这里根据食物的位置来控制方向防止用户随意改变方向导致游戏崩溃.document.onkeydown=function(e){//方向由蛇头决定,初始蛇只有2个小方块组成,所以蛇的方向为s[1]-s[0]d=s[1]-s[0]===(x=[-1,-20,1,20][e||事件].keyCode-37]||d)?d:x;}!(function(){s.unshift(x=s[0]+d);//如果蛇撞到墙或自己,游戏结束if(s.indexOf(x,1)>0||x<0||x>399||d==1&&x%20==0||d==-1&&x%20==19)returnalert('gameover');//然后开始绘制colorofthesnakenodew(x,'#e641d3');//判断蛇是不是在吃食物,如果是,就随机生成一个节点,就是新食物的坐标,即Math.random()方法的意思是取一个随机数,因为方向可能是负数,所以用~~符号表示绝对值为正数。~的意思是先取反再减一。if(x==f){while(s.indexOf(f=~~(Math.random()*399))>0);//重绘食物颜色w(f,'#35e3dc');}else{//当蛇进食时食物,它的身体会变长,所以不会改变蛇的轨迹w(s.pop(),'#535353');}//这是递归的写法setTimeout(arguments.callee,300);})();//这也是写自调用函数docu的一种方式ment.body.appendChild(c);})();到这里,分裂就结束了。其实这里的逻辑并不难。困难的是了解蛇的坐标、蛇的运动轨迹和食物。就看个人的数学知识了,哈哈。终于把这么多代码整合成一行代码,可以装酷了!ps:本文代码基于国外高手20多行js代码实现贪吃蛇。在源码的基础上进行分析,修改打包。如果您不喜欢它,请不要喷它。我创建了一个QQ群供大家学习交流。希望与您合作愉快,互相帮助,交流学习。以下为群二维码:
