资讯专栏INFORMATION COLUMN

装逼的最高境界---一行js代码完成一个简易版的贪吃蛇游戏

hidogs / 2400人阅读

摘要:有些奇淫技巧玩好的话,就能提升自己的逼格,这不,一行代码实现一个贪吃蛇小游戏就成了装逼到了最高境界嘛代码如下当前浏览器不支持标签游戏结束我不是来装逼的。

有些奇淫技巧玩好的话,就能提升自己的逼格,这不,一行js代码实现一个贪吃蛇小游戏就成了装逼到了最高境界嘛!代码如下:

(function(){var s = [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");function w(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);if(s.indexOf(x,1) > 0 || x < 0 || x > 399 || d == 1 && x % 20 == 0 || d == -1 && x % 20 == 19)return alert("游戏结束!");w(x,"#2396ef");x === f ? (()=>{while (s.indexOf(f = ~~(Math.random() * 399)) > 0);w(f,"#35e3dc");})() : w(s.pop(),"#535353");setTimeout(arguments.callee,300);})();document.body.appendChild(c);})();

ps:我不是来装逼的。!

好了,让我们来运行一下这行代码,看一下效果:

看动图看着不过瘾?,好,你自己去线上看看demo可以撒,具体示例。

装逼完成,

好了,言归正传,我怎么可能是来装逼的,我要来分析一下,这个是怎么玩的,这才是我的目的。

让我们拆分代码来看:

首先,最外层包裹了一个自调用函数,如下:

(function(){
    //具体内容
})();
//自调用函数当然不止这样的写法

然后第二步,要画一个场景,那很明显,要用HTML5canvas标签,我们可以采用document.createElement()这个方法来创建一个元素,继续:

(function(){
    //创建canvas标签
    var c = document.createElement("canvas");
})();

蛇运动的场景肯定是固定大小的,也就是说,我们要给canvas设置宽和高,在这里,我就是设置的400X400,然后给场景加一个背景。就这样:

(function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
})();

创建了canvas元素,我们要添加到DOM网页中去,所以用appendChild()来添加。如下:

(function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
    document.body.appendChild(c);
})();

哦,有些浏览器可能不支持canvas标签,所以我们不能忘了给一个优雅的提示:

(function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
    c.textContent="当前浏览器不支持canvas标签";
    document.body.appendChild(c);
})();

场景画好了,接下来,我们要在场景上画蛇,所以canvas.getContext("2d")这个方法是必不可少的。

 (function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
   var b = c.getContext("2d");
   document.body.appendChild(c);
})();

接下来分析蛇的构成,实际上这里的场景,我们可以看成是40020*20的块组成,那么蛇也就可以看成一个块一个块的组成,用技术术语来说就是一个队列,也就是一个数组,[20]。在这里初始化蛇为2个块,也就是[20,20],那么蛇初始化位置还是稍微调整一下嘛,所以也就改成[40,40],其实在这里第一次出现的时候,是隐藏了一个食物的,默认就在蛇初始化位置的下一格,然后蛇会立即吃掉,然后就随机出现下一个食物的位置了,因此默认食物的位置是40。为了一个方便细小的微差,就稍微调大一点,为43。好了,现在我们要知道蛇运行的方向,蛇可以上下左右活动,那么,我们定义为s[1] - s[0],这是根据位置来计算的。咱们先定义蛇再说:

(function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
   var b = c.getContext("2d");
   var s = [41,40],//这里41也是有讲究的
       d = 1,//定义蛇活动方向,默认向右
       f = 42;//默认食物的位置
   document.body.appendChild(c);
})();

接下来,开始绘制蛇,蛇活动的轨迹与食物。定义一个函数,利用canvas.fillStyle()填充背景,在这里蛇与食物还有蛇活动的轨迹都是一个小方块矩形,这样我们就使用canvas.fillRect()来绘制一个矩形,这个方法有四个参数,如下图所示:

蛇活动的轨迹坐标,也就是定义的蛇数组的坐标,因此第一个参数就是s % 20 * 20,第二个参数就是~~(s / 20 * 20)。关于~~这个操作符,如果不理解的话,可以看我的文章浅谈JavaScript位操作符。这里感觉有些抽象,实际上,需要靠自己的想象力来想象理解。

(function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
   var b = c.getContext("2d");
   var s = [41,40],//这里41也是有讲究的,代表默认向右方向
       d = 1,//定义蛇活动方向,默认向右,蛇运动方向为s[1] - s[0]
       f = 42;//默认食物的位置
   //这个函数既是绘制蛇方块,也是绘制食物与蛇活动轨迹的定义
   function w(s,c){
       b.fillStyle = c;
       b.fillRect(s % 20 * 20,~~(s / 20 * 20),18,18);
   }
   document.body.appendChild(c);
})();

蛇每吃掉一个食物,也就是往数组中添加一个20*20的小块,当然为了区分方向,这里的小块宽高应该与绘制的矩形宽高有关。因此,我们还要定义一个变量来代表蛇吃掉食物后,随机出现的下一个食物出现的位置。

(function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
   var b = c.getContext("2d");
   var s = [41,40],//这里41也是有讲究的,代表默认向右方向
       d = 1,//定义蛇活动方向,默认向右,蛇运动方向为s[1] - s[0]
       f = 42,//默认食物的位置
       x;
   //这个函数既是绘制蛇方块,也是绘制食物与蛇活动轨迹的定义
   function w(s,c){
       b.fillStyle = c;
       b.fillRect(s % 20 * 20,~~(s / 20 * 20),18,18);
   }
   document.body.appendChild(c);
})();

接下来就是用户按键盘的方向键,当然也可以是wsad字母键来控制蛇活动的方向。不过我们需要知道键盘键的keyCode,方向键的keyCode分别是:向左:37,向上:38,,向右:39,向下:40。键盘事件为onkeydown


(function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
   var b = c.getContext("2d");
   var s = [41,40],//这里41也是有讲究的,代表默认向右方向
       d = 1,//定义蛇活动方向,默认向右,蛇运动方向为s[1] - s[0]
       f = 42,//默认食物的位置
       x;
   //这个函数既是绘制蛇方块,也是绘制食物与蛇活动轨迹的定义
   function w(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;
   }
   document.body.appendChild(c);
})();

然后蛇吃掉一个食物就应该添加下一个食物,在这里用unshift()方法来添加数组。

(function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
   var b = c.getContext("2d");
   var s = [41,40],//这里41也是有讲究的,代表默认向右方向
       d = 1,//定义蛇活动方向,默认向右,蛇运动方向为s[1] - s[0]
       f = 42,//默认食物的位置
       x;
   //这个函数既是绘制蛇方块,也是绘制食物与蛇活动轨迹的定义
   function 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 || event].keyCode - 37 ] || d) ? d : x;
   }
   !(function(){
       s.unshift(x = s[0] + d);
   })();//这也是一种自调用函数写法
   document.body.appendChild(c);
})();

接下来判断蛇如果撞墙或者撞到了自身,则游戏结束。

(function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
   var b = c.getContext("2d");
   var s = [41,40],//这里41也是有讲究的,代表默认向右方向
       d = 1,//定义蛇活动方向,默认向右,蛇运动方向为s[1] - s[0]
       f = 42,//默认食物的位置
       x;
   //这个函数既是绘制蛇方块,也是绘制食物与蛇活动轨迹的定义
   function 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 || event].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)return alert("游戏结束");
   })();//这也是一种自调用函数写法
   document.body.appendChild(c);
})();

然后开始画食物,以及判断食物是否被蛇吃掉,如果吃掉了,则随机生成下一个食物。

(function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
   var b = c.getContext("2d");
   var s = [41,40],//这里41也是有讲究的,代表默认向右方向
       d = 1,//定义蛇活动方向,默认向右,蛇运动方向为s[1] - s[0]
       f = 42,//默认食物的位置
       x;
   //这个函数既是绘制蛇方块,也是绘制食物与蛇活动轨迹的定义
   function 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 || event].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)return alert("游戏结束");
       //然后开始画蛇节点的颜色
        w(x,"#e641d3");
        //判断蛇是不是吃到食物,如果吃到则重新随机生成一个节点也就是新食物的坐标,Math.random()方法表示取随机数,因为方向有可能是负的,所以用到了~~符号表示取绝对值到正数.~就是先取反再减一的意思.
        if(x == f){
            while (s.indexOf(f = ~~(Math.random() * 399)) > 0);
            //重新画食物颜色
            w(f,"#35e3dc");
        }else{
            //蛇吃到食物,蛇身会变长,所以不会改变蛇的运动轨迹
            w(s.pop(),"#535353");
        }
   })();//这也是一种自调用函数写法
   document.body.appendChild(c);
})();

最后,让蛇按一定的时间运行,如下:

  (function(){
    //创建canvas标签
    var c = document.createElement("canvas");
    c.width = 400;
    c.height = 400;
    c.style.background = "#535353";
   var b = c.getContext("2d");
   var s = [41,40],//这里41也是有讲究的,代表默认向右方向
       d = 1,//定义蛇活动方向,默认向右,蛇运动方向为s[1] - s[0]
       f = 42,//默认食物的位置
       x;
   //这个函数既是绘制蛇方块,也是绘制食物与蛇活动轨迹的定义
   function 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 || event].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)return alert("游戏结束");
       //然后开始画蛇节点的颜色
        w(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);
   })();//这也是一种自调用函数写法
   document.body.appendChild(c);
})();

到此为止,就拆分完了,其实这里的逻辑不算难,难的是计算蛇与蛇运动轨迹还有食物的坐标。能够理解透,就看个人的数学知识了,哈哈。最后,将这么多代码整合成一行代码,就可以好好的装逼了!

ps:本文代码借鉴国外某大神20多行js代码实现贪吃蛇,在源代码基础上进行分析并加以修改封装而成,不喜勿喷。

鄙人创建了一个QQ群,供大家学习交流,希望和大家合作愉快,互相帮助,交流学习,以下为群二维码:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/55008.html

相关文章

  • 逼的最高境界---一行js代码完成一个简易版的贪吃游戏

    摘要:有些奇淫技巧玩好的话,就能提升自己的逼格,这不,一行代码实现一个贪吃蛇小游戏就成了装逼到了最高境界嘛代码如下当前浏览器不支持标签游戏结束我不是来装逼的。 有些奇淫技巧玩好的话,就能提升自己的逼格,这不,一行js代码实现一个贪吃蛇小游戏就成了装逼到了最高境界嘛!代码如下: (function(){var s = [41,40],d = 1,f = 43,x,c = document.cr...

    vincent_xyb 评论0 收藏0
  • 深入理解js

    摘要:详解十大常用设计模式力荐深度好文深入理解大设计模式收集各种疑难杂症的问题集锦关于,工作和学习过程中遇到过许多问题,也解答过许多别人的问题。介绍了的内存管理。 延迟加载 (Lazyload) 三种实现方式 延迟加载也称为惰性加载,即在长网页中延迟加载图像。用户滚动到它们之前,视口外的图像不会加载。本文详细介绍了三种延迟加载的实现方式。 详解 Javascript十大常用设计模式 力荐~ ...

    caikeal 评论0 收藏0
  • 在手机或电脑浏览器上玩贪吃

    摘要:贪吃蛇源代码地址在手机浏览器上的显示效果贪吃蛇的基本框架首先确定蛇的移动区域,由一组标签构成,给予一个宽高,就组成了蛇的活动区域。以最小宽度为基准贪吃蛇的框架补全在里添加要创建个来作为贪吃蛇的活动场所。 贪吃蛇 源代码地址:https://github.com/jiaoshibo/... 在手机浏览器上的显示效果 showImg(https://segmentfault.com/img...

    Big_fat_cat 评论0 收藏0
  • 在手机或电脑浏览器上玩贪吃

    摘要:贪吃蛇源代码地址在手机浏览器上的显示效果贪吃蛇的基本框架首先确定蛇的移动区域,由一组标签构成,给予一个宽高,就组成了蛇的活动区域。以最小宽度为基准贪吃蛇的框架补全在里添加要创建个来作为贪吃蛇的活动场所。 贪吃蛇 源代码地址:https://github.com/jiaoshibo/... 在手机浏览器上的显示效果 showImg(https://segmentfault.com/img...

    zhangfaliang 评论0 收藏0
  • python完成简单的贪吃游戏附编号

      此篇文章主要是详细介绍了python完成简单的贪吃蛇小游戏附编号,文章内容紧扣主题进行详尽的基本介绍,具有很强的参考意义,需用的朋友可以学习一下  序言:  不知道有没有同学们和我一样,最开始触碰程序编程的动机就是为了做一个游戏打?  接下来要跟大家分享是指一个pygame所写的贪食蛇手机游戏:  贪食蛇这一个手机游戏在编程设计里的熟客,由于:  简易,最基本游戏情节你只需要蛇和食物2个就可以...

    89542767 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<