JS实现的贪吃蛇游戏完整实例


Posted in Javascript onJanuary 18, 2019

本文实例讲述了JS实现的贪吃蛇游戏。分享给大家供大家参考,具体如下:

思想:

1、设计蛇:属性有宽、高、方向、状态(有多少节),方法:显示,跑

2、设计食物:属性宽、高

3、显示蛇:根据状态向地图里加元素

4、蛇跑起来:下一节到前一节的位置,蛇头根据方向变,删除原来的蛇,新建蛇;当出界时,死亡,初始化;当蛇头吃到自己的时候,死亡,初始化

5、食物被吃掉,蛇加一节,去掉原来的食物,生成新的食物

6、添加定时器,绑定按键

完整示例:

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
     content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style type="text/css">
    body {
      margin: 0;
      padding: 0;
    }
    .main {
      width: 800px;
      height: 400px;
      margin: 50px auto;
    }
    .btn {
      width: 100px;
      height: 40px;
    }
    .map {
      position: relative;
      width: 800px;
      height: 400px;
      background: #ccc;
    }
  </style>
</head>
<body>
<div class="main">
  <button class="btn" id="begin">开始游戏</button>
  <div class="map" id="map"></div>
  <script type="text/javascript">
    var map = document.getElementById('map');
    // 使用构造方法创建蛇,
    function Snake()
    {
      // 设置蛇的宽、高、默认走的方向
      this.width = 10;
      this.height = 10;
      this.direction = 'right';
      // 记住蛇的状态,当吃完食物的时候,就要加一个,初始为3个小点为一个蛇,
      this.body = [
        {x:2, y:0},  // 蛇头,第一个点
        {x:1, y:0},  // 蛇脖子,第二个点
        {x:0, y:0}  // 蛇尾,第三个点
      ];
      // 显示蛇
      this.display = function() {
        // 创建蛇
        for (var i=0; i<this.body.length; i++) {
          if (this.body[i].x != null) {  // 当吃到食物时,x==null,不能新建,不然会在0,0处新建一个
            var s = document.createElement('div');
            // 将节点保存到状态中,以便于后面删除
            this.body[i].flag = s;
            // 设置宽高
            s.style.width = this.width + 'px';
            s.style.height = this.height + 'px';
            s.style.borderRadius = "50%";
            s.style.background = "rgb(" + Math.floor(Math.random()*256) + "," + Math.floor(Math.random()*256) + "," + Math.floor(Math.random()*256) + ")";
            // 设置位置
            s.style.position = 'absolute';
            s.style.left = this.body[i].x * this.width + 'px';
            s.style.top = this.body[i].y * this.height + 'px';
            // 添加进去
            map.appendChild(s);
          }
        }
      };
      // 让蛇跑起来,后一个元素到前一个元素的位置
      // 蛇头根据方向处理,所以i不能等于0
      this.run = function() {
        // 后一个元素到前一个元素的位置
        for (var i=this.body.length-1; i>0; i--) {
          this.body[i].x = this.body[i-1].x;
          this.body[i].y = this.body[i-1].y;
        }
        // 根据方向处理蛇头
        switch(this.direction)
        {
          case "left":
            this.body[0].x -= 1;
            break;
          case "right":
            this.body[0].x += 1;
            break;
          case "up":
            this.body[0].y -= 1;
            break;
          case "down":
            this.body[0].y += 1;
            break;
        }
        // 判断是否出界,一蛇头判断,出界的话,
        if (this.body[0].x < 0 || this.body[0].x > 79 || this.body[0].y < 0 || this.body[0].y > 39) {
          clearInterval(timer);  // 清除定时器,
          alert("你瞎吗?撞死了!");
          // 删除旧的
          for (var i=0; i<this.body.length; i++) {
            if (this.body[i].flag != null) {  // 如果刚吃完就死掉,会加一个值为null的
              map.removeChild(this.body[i].flag);
            }
          }
          this.body = [  // 回到初始状态,
            {x:2, y:0},
            {x:1, y:0},
            {x:0, y:0}
          ];
          this.direction = 'right';
          this.display();  // 显示初始状态
          return false;  // 结束
        }
        // 判断蛇头吃到食物,xy坐标重合,
        if (this.body[0].x == food.x && this.body[0].y == food.y) {
          // 蛇加一节,因为根据最后节点定,下面display时,会自动赋值的
          this.body.push({x:null, y:null, flag: null});
          // 清除食物,重新生成食物
          map.removeChild(food.flag);
          food.display();
        }
        // 吃到自己死亡,从第五个开始与头判断,因为前四个永远撞不到
        for (var i=4; i<this.body.length; i++) {
          if (this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y) {
            clearInterval(timer);  // 清除定时器,
            alert("傻子!你怎么能吃自己呢?");
            // 删除旧的
            for (var i=0; i<this.body.length; i++) {
              if (this.body[i].flag != null) {  // 如果刚吃完就死掉,会加一个值为null的
                map.removeChild(this.body[i].flag);
              }
            }
            this.body = [  // 回到初始状态,
              {x:2, y:0},
              {x:1, y:0},
              {x:0, y:0}
            ];
            this.direction = 'right';
            this.display();  // 显示初始状态
            return false;  // 结束
          }
        }
        // 先删掉初始的蛇,在显示新蛇
        for (var i=0; i<this.body.length; i++) {
          if (this.body[i].flag != null) {  // 当吃到食物时,flag是等于null,且不能删除
            map.removeChild(this.body[i].flag);
          }
        }
        // 重新显示蛇
        this.display();
      }
    }
    // 构造食物
    function Food()
    {
      this.width = 10;
      this.height = 10;
      this.display = function() {
        var f = document.createElement('div');
        this.flag = f;
        f.style.width = this.width + 'px';
        f.style.height = this.height + 'px';
        f.style.background = 'red';
        f.style.borderRadius = '50%';
        f.style.position = 'absolute';
        this.x = Math.floor(Math.random()*80);
        this.y = Math.floor(Math.random()*40);
        f.style.left = this.x * this.width + 'px';
        f.style.top = this.y * this.height + 'px';
        map.appendChild(f);
      }
    }
    var snake = new Snake();
    var food = new Food();
    snake.display();  // 初始化显示
    food.display();
    // 给body加按键事件,上下左右
    document.body.onkeydown = function(e) {
      // 有事件对象就用事件对象,没有就自己创建一个,兼容低版本浏览器
      var ev = e || window.event;
      switch(ev.keyCode)
      {
        case 38:
          if (snake.direction != 'down') {  // 不允许返回,向上的时候不能向下
            snake.direction = "up";
          }
          break;
        case 40:
          if (snake.direction != "up") {
            snake.direction = "down";
          }
          break;
        case 37:
          if (snake.direction != "right") {
            snake.direction = "left";
          }
          break;
        case 39:
          if (snake.direction != "left") {
            snake.direction = "right";
          }
          break;
      }
    };
    // 点击开始时,动起来
    var begin = document.getElementById('begin');
    var timer;
    begin.onclick = function() {
      clearInterval(timer);
      // timer = setInterval(snake.run(), 500);  // 先执行run函数,把执行得到的结果,每500毫秒执行一次,不会在执行内部代码
      timer = setInterval("snake.run()", 500); // 小技巧,每500毫秒执行字符串,字符串执行内部代码
    };
  </script>
</div>
</body>
</html>

使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码,可得到如下运行效果:

JS实现的贪吃蛇游戏完整实例

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
jquery 插件 web2.0分格的分页脚本,可用于ajax无刷新分页
Dec 25 Javascript
jQuery 事件队列调整方法
Sep 18 Javascript
jquery组件使用中遇到的问题整理及解决
Feb 21 Javascript
用模版生成HTML的的框架jquery.tmpl使用详解
Jan 07 Javascript
浏览器兼容性问题大汇总
Dec 17 Javascript
angularJS Provider、factory、service详解及实例代码
Sep 21 Javascript
easyui-combobox 实现简单的自动补全功能示例
Nov 08 Javascript
解决vue.js this.$router.push无效的问题
Sep 03 Javascript
手把手教你写一个微信小程序(推荐)
Oct 17 Javascript
小程序点击图片实现自动播放视频
May 29 Javascript
详解vue-cli3多环境打包配置
Mar 28 Javascript
浅析Vue 防抖与节流的使用
Nov 14 Javascript
jquery的$().each和$.each的区别
Jan 18 #jQuery
使用form-create动态生成vue自定义组件和嵌套表单组件
Jan 18 #Javascript
jquery层次选择器的介绍
Jan 18 #jQuery
js实现图片放大并跟随鼠标移动特效
Jan 18 #Javascript
vue.js的双向数据绑定Object.defineProperty方法的神奇之处
Jan 18 #Javascript
jQuery无冲突模式详解
Jan 17 #jQuery
JQuery判断radio单选框是否选中并获取值的方法
Jan 17 #jQuery
You might like
phpmyadmin里面导入sql语句格式的大量数据的方法
2010/06/05 PHP
PHP培训要多少钱
2017/06/06 PHP
作为PHP程序员你要知道的另外一种日志
2018/07/30 PHP
PHP进阶学习之命名空间基本用法分析
2019/06/18 PHP
Jquery 表单取值赋值的一些基本操作
2009/10/11 Javascript
jquery下onpropertychange事件的绑定方法
2010/08/01 Javascript
javascript 运算数的求值顺序
2011/08/23 Javascript
跨浏览器的事件对象介绍
2012/06/27 Javascript
JQuery调webservice实现邮箱验证(检测是否可用)
2013/05/21 Javascript
jQuery实现页面滚动时动态加载内容的方法
2015/03/20 Javascript
JS+CSS实现类似QQ好友及黑名单效果的树型菜单
2015/09/22 Javascript
详解Javacript和AngularJS中的Promises
2016/02/09 Javascript
JavaScript中的各种操作符使用总结
2016/05/26 Javascript
微信小程序之仿微信漂流瓶实例
2016/12/09 Javascript
zTree实现节点修改的实时刷新功能
2017/03/20 Javascript
微信小程序icon组件使用详解
2018/01/31 Javascript
ES7之Async/await的使用详解
2019/03/28 Javascript
vue项目打包为APP,静态资源正常显示,但API请求不到数据的操作
2020/09/12 Javascript
Node 使用express-http-proxy 做api网关的实现
2020/10/15 Javascript
Django 前后台的数据传递的方法
2017/08/08 Python
详谈Python3 操作系统与路径 模块(os / os.path / pathlib)
2018/04/26 Python
Python实现两个list求交集,并集,差集的方法示例
2018/08/02 Python
Python中几种属性访问的区别与用法详解
2018/10/10 Python
python实现感知器算法(批处理)
2019/01/18 Python
pandas DataFrame 删除重复的行的实现方法
2019/01/29 Python
Python 实现一个手机号码获取妹子名字的功能
2019/09/25 Python
windows、linux下打包Python3程序详细方法
2020/03/17 Python
Python unittest基本使用方法代码实例
2020/06/29 Python
Forever 21美国官网:美国标志性快时尚品牌
2017/02/20 全球购物
美国牛仔品牌:True Religion
2018/11/16 全球购物
Brora官网:英国领先的羊绒服装品牌
2019/08/28 全球购物
手工社团活动方案
2014/02/17 职场文书
大学学习个人的自我评价
2014/02/18 职场文书
学位证书委托书
2014/09/30 职场文书
离婚起诉状范本
2015/05/19 职场文书
2016春季幼儿园小班开学寄语
2015/12/03 职场文书