JavaScript写个贪吃蛇小游戏(超详细)


Posted in Javascript onMarch 17, 2020

贪吃蛇大家都玩过,但你会制作嘛?听起来好像很难的样子,其实非常的简单,话不多说直接上代码

我们先把dom结构写出来

<div id="content">
      <div id="snake">
          <div class="box head"></div>
          <div class="box"></div>

      </div>
  
    </div>

其中,content为整个布局的大盒子,snake就是蛇,里面的box就是他的身体,为了区分头部我们给第一个box加了个head名字用于区分,下面我们再把css加上

<style>
    .box{
      width: 60px;
      height: 60px;
      background-color: red;
      position:absolute;
      left: 0;
      top: 0;
      line-height: 60px;
    }
    .head{
      background-color: yellowgreen;
    }
  </style>

我们给蛇的每一节的宽高设置为60像素,并给了一个定位,因为如果不加定位的话无法让他脱离文档流(在页面中飘起来),而且后续也无法通过left和top来判断他的坐标.

JavaScript写个贪吃蛇小游戏(超详细)

好的这样我们就得到了一条可爱的小蛇(然鹅并没有看出来哪里可爱- -)。什么?你问我他的头哪去了,很简单,在给元素加了定位以后后面的元素会覆盖掉前面的元素,所以只是头部和身体重叠了你看不到而已。
随后咱们得让这条蛇动起来是吧,那么我们怎么让他动起来呢?原理很简单,我们可以设置一个定时器,每过一个时间就让他动一下,而怎么让他动呢,只需要设置一个数值,让这个值每动一下就+=60,然后通过判断是上下动还是左右动,来给元素的left与top赋值。我们把逻辑写成代码,就出来了如下的代码

<script>
    var boxs = document.querySelectorAll(".box");
    var snake_x = 0;
    var snake_y = 0;
    var turn  = "right";
    setInterval(function(){
      snakeMove();
    },100)
    function snakeMove(){ 
      switch( turn ){
        case "right": snake_x += 60;break;
        case "left" : snake_x -= 60;break;
        case "top"  : snake_y -= 60;break;
        case "bottom": snake_y += 60;break;
      }

      for(var i = boxs.length - 1; i > 0 ; i --){
        boxs[i].style.left = boxs[i - 1].style.left;
        boxs[i].style.top = boxs[i - 1].style.top;
        
      }
      boxs[i].style.left = snake_x + "px";
      boxs[i].style.top = snake_y + "px";

    }
document.onkeydown = function(evt){
      var e = evt || event;
      var keyCode = e.keyCode || e.which;
      switch( keyCode ){
        case 37 : turn = "left";break;
        case 38 : turn = "top";break;
        case 39 : turn = "right";break;
        case 40 : turn = "bottom";break;
      }
    }

</script>

上述代码中,我们给小蛇的初始位置的x和y的坐标都设置为0,并且默认初始向右走,通过键盘上方向键的输入,来改变他的方向。其中,难点在于

for(var i = boxs.length - 1; i > 0 ; i --){
        boxs[i].style.left = boxs[i - 1].style.left;
        boxs[i].style.top = boxs[i - 1].style.top;
        
      }
      boxs[i].style.left = snake_x + "px";
      boxs[i].style.top = snake_y + "px";

这一块代码,这块代码的目的是让后面的元素跟着前面的走,也就是让蛇的每一块身体都跟着上一块去运动,然后最后再给头部设置为snake_x和snake_y当前的值即可,这样就形成了第一块(头部)坐标为
snake_x,snake_y实时变化的值,第二块为第一块之前的值,第三块为第二块之前的值。。。以此类推就得到了一个身体跟着头部走的效果

JavaScript写个贪吃蛇小游戏(超详细)

但是当你把代码输进去以后一运行会发现,这条小蛇过于顽皮,以至于走到边界以后还会无限的向前走,那这不行啊,总不能让蛇跑了不是,所以得给小蛇加上一个边界

var snake_x_max = document.documentElement.clientWidth ;
    var snake_y_max = document.documentElement.clientHeight;
if(snake_x > snake_x_max){
        snake_x = 0;
      }
      if(snake_x < 0){
        snake_x = snake_x_max;
      }
      if(snake_y > snake_y_max){
        snake_y = 0;
      }
      if(snake_y < 0){
        snake_y = snake_y_max;
      }

这里我们设置x和y的最大值为当前窗口的宽高,然后通过if语句进行判断,如果当前坐标大于了最大值,就讲当前坐标归0,如果小于0的话(也就是跑到了左边的边界),就将当前坐标设置为最大值,这样就可以得到一个边界啦

JavaScript写个贪吃蛇小游戏(超详细)

你以为这样就完事啦?nonono,没有食物吃的蛇怎么能叫做贪吃蛇呢,那是没有灵魂哒。下面我们开始制作食物(不能让蛇饿着是吧)。

<div id="food">
  
      </div>

然后给他加个css

#food{
    width: 60px;
    height: 60px;
    position: absolute;
    background: greenyellow;
  }

然后再绑定一下元素并将他的left和top值设为范围内随机数,这样可以做到随机位置生成

var fd=document.getElementById("food");
    fd.style.left=Math.random()*snake_x_max+"px";
    fd.style.top=Math.random()*snake_y_max+"px";

好的这样我们就得到了一个随机生成的食物

JavaScript写个贪吃蛇小游戏(超详细)

不过我们的小蛇好像对食物并没有什么兴趣呢,路过以后并不会吃掉,所以我们得给他加一个碰撞检测吧,碰撞检测的逻辑很简单,只需要让食物的left值与头部的left值相减的绝对值<=食物的大小,并且食物的top值与头部的top值相减的绝对值<=食物的大小,设置小于等于是因为如果直接用相等来判断的话,必须两个元素完全重合才行,我们需要的是碰到边缘就算迟到,所以用两个数值相减小于等于来做。然后判断当头部与食物发生碰撞时,将蛇的身体部分克隆一块出来放到蛇的身体里面,并让食物的位置重新刷新(适用克隆为偷懒方法,此偷懒方法仅适用于当小蛇开局自带一个身体的时候,如果小蛇开局不自带身体的话,我们无法克隆已有身体,只能通过createElement去新创建一个身体块出来并添加className后再添加到父元素中去才行)。下面我们把逻辑转换为代码

var dl=snake_x;
    var dt=snake_y;
    var fl=fd.style.left;
    var ft=fd.style.top;
    var dv=document.querySelectorAll("#snake div");
    var sk=document.getElementById("snake");
    var a2=Number(fl.substring(0,fl.indexOf("px")));
    var b2=Number(ft.substring(0,ft.indexOf("px")));
    if(Math.abs(dl-a2)<=60&&Math.abs(dt-b2)<=60){
       fd.style.left=Math.random()*1000+"px";
       fd.style.top=Math.random()*800+"px";
       sk.appendChild(dv[1].cloneNode());
       boxs = document.querySelectorAll(".box");
    }

其中那一大长串的substring的方法是因为获取到的left与top的值的格式是例如”200px”这样的数组,无法进行数学运算,所以要把px给截掉,并将剩下的字符串”200”转换成number类型才可以进行数学运算。

JavaScript写个贪吃蛇小游戏(超详细)

这样一个简单的贪吃蛇就做好啦~
啥?你问我什么什么类似碰到自己会死这样更多的规则机制咋没写,肯定是因为我懒啊!我连createElement都懒得用直接克隆一个出来了,咋会勤快到把剩下这么多的机制补全呢哈哈。基础机制我已经写出来了,各种奇奇怪怪的机制还是留给小伙伴们自由发挥吧~
PS:大家完全可以把头部的背景图片改成你小伙伴的照片,再把食物改成一些你想让ta吃的东西,可以拿来恶搞啊哈哈哈

到此这篇关于JavaScript写个贪吃蛇小游戏(超详细)的文章就介绍到这了,更多相关js 贪吃蛇内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
推荐一些非常不错的javascript学习资源站点
Aug 29 Javascript
Javascript结合css实现网页换肤功能
Nov 02 Javascript
到处都是jQuery选择器的年代 不了解它们的性能,行吗
Jun 18 Javascript
精心挑选的15款优秀jQuery 本特效插件和教程
Aug 06 Javascript
JS 加入收藏夹的代码(主流浏览器通用)
May 13 Javascript
LABjs、RequireJS、SeaJS的区别
Mar 04 Javascript
点击button获取text内容并改变样式的js实现
Sep 09 Javascript
在JavaScript应用中实现延迟加载的方法
Jun 25 Javascript
jQuery模拟原生态App上拉刷新下拉加载更多页面及原理
Aug 10 Javascript
基于HTML模板和JSON数据的JavaScript交互(移动端)
Apr 06 Javascript
AngularJS在IE下取数据总是缓存问题的解决方法
Aug 05 Javascript
Angular使用 ng-img-max 调整浏览器中的图片的示例代码
Aug 17 Javascript
JS+CSS+HTML实现“代码雨”类似黑客帝国文字下落效果
Mar 17 #Javascript
js实现简单点赞操作
Mar 17 #Javascript
vue+ESLint 配置保存 自动格式化代码
Mar 17 #Javascript
HTML+JS实现“代码雨”效果源码(黑客帝国文字下落效果)
Mar 17 #Javascript
JavaScript实现横版菜单栏
Mar 17 #Javascript
JavaScript实现留言板案例
Mar 17 #Javascript
es6函数之严格模式用法实例分析
Mar 17 #Javascript
You might like
PHP动态分页函数,PHP开发分页必备啦
2011/11/07 PHP
本地机apache配置基于域名的虚拟主机详解
2013/08/10 PHP
Centos 6.5系统下编译安装PHP 7.0.13的方法
2016/12/19 PHP
Javascript中判断变量是数组还是对象(array还是object)
2013/08/14 Javascript
JS中for循序中延迟加载动态效果的具体实现
2013/08/18 Javascript
禁止页面刷新让F5快捷键及右键都无效
2014/01/22 Javascript
使用jquery选择器如何获取父级元素、同级元素、子元素
2014/05/14 Javascript
一个JavaScript处理textarea中的字符成每一行实例
2014/09/22 Javascript
javascript实现类似超链接的效果
2014/12/26 Javascript
js实现跟随鼠标移动且带关闭功能的图片广告实例
2015/02/26 Javascript
JS基于ocanvas插件实现的简单画板效果代码(附demo源码下载)
2016/04/05 Javascript
iframe中使用jquery进行查找的方法【案例分析】
2016/06/17 Javascript
js css+html实现简单的日历
2016/07/14 Javascript
Node.js 实现简单小说爬虫实例
2016/11/18 Javascript
浅析jQuery操作select控件的取值和设值
2016/12/07 Javascript
VUE实现表单元素双向绑定(总结)
2017/08/08 Javascript
Vue-router 中hash模式和history模式的区别
2018/07/24 Javascript
解决vuejs项目里css引用背景图片不能显示的问题
2018/09/13 Javascript
基于JavaScript判断两个对象内容是否相等
2020/01/10 Javascript
通过实例解析js可枚举属性与不可枚举属性
2020/12/02 Javascript
[01:28:43]2014 DOTA2华西杯精英邀请赛5 24 DK VS CIS
2014/05/25 DOTA
python编码总结(编码类型、格式、转码)
2016/07/01 Python
python爬虫headers设置后无效的解决方法
2017/10/21 Python
从0开始的Python学习016异常
2019/04/08 Python
PyCharm导入python项目并配置虚拟环境的教程详解
2019/10/13 Python
Anaconda+Pycharm环境下的PyTorch配置方法
2020/03/13 Python
python openssl模块安装及用法
2020/12/06 Python
CSS3盒子模型详解
2013/04/24 HTML / CSS
乐天旅游香港网站:日本饭店预订
2017/11/29 全球购物
英国女性时尚鞋类的潮流制造者:Koi Footwear
2018/10/19 全球购物
您的时尚,您的生活方式:DTLR Villa
2019/12/25 全球购物
论文评语大全
2014/04/29 职场文书
工作作风建设心得体会
2014/10/22 职场文书
大学四年个人总结
2015/03/03 职场文书
2019暑假学生安全口号
2019/06/27 职场文书
pytorch Dropout过拟合的操作
2021/05/27 Python