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下attr和removeAttr的使用方法
Dec 28 Javascript
JS将所有对象s的属性复制给对象r(原生js+jquery)
Jan 25 Javascript
jquery实现可横向和竖向展开的动态下滑菜单效果
Aug 24 Javascript
JS实现浏览器状态栏文字从右向左弹出效果代码
Oct 27 Javascript
常常会用到的截取字符串substr()、substring()、slice()方法详解
Dec 16 Javascript
Bootstrap下拉菜单Dropdowns的实现代码
Mar 17 Javascript
浅谈ECMAScript6新特性之let、const
Aug 02 Javascript
基于jquery实现五星好评
Nov 18 jQuery
实例介绍JavaScript中多种组合继承
Jan 20 Javascript
微信小程序实现吸顶效果
Jan 08 Javascript
阿望教你用vue写扫雷小游戏
Jan 20 Javascript
详解Vue 数据更新了但页面没有更新的 7 种情况汇总及延伸总结
May 28 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
PHP的一个完整SMTP类(解决邮件服务器需要验证时的问题)
2006/10/09 PHP
比较简单的百度网盘文件直链PHP代码
2013/03/24 PHP
Thinkphp使用mongodb数据库实现多条件查询方法
2014/06/26 PHP
简单的自定义php模板引擎
2016/08/26 PHP
jQuery formValidator表单验证插件开源了 含API帮助、源码、示例
2008/08/14 Javascript
基于Jquery的简单&amp;简陋Tabs插件代码
2010/02/09 Javascript
javascript实现的在当前窗口中漂浮框的代码
2010/03/15 Javascript
面向对象设计模式的核心法则
2013/11/10 Javascript
ie7+背景透明文字不透明超级简单的实现方法
2014/01/17 Javascript
JavaScript数据结构和算法之二叉树详解
2015/02/11 Javascript
jQuery实现将页面上HTML标签换成另外标签的方法
2015/06/09 Javascript
JavaScript判断数组是否存在key的简单实例
2016/08/03 Javascript
基于layui框架响应式布局的一些使用详解
2019/09/16 Javascript
解决layui数据表格排序图标被超出的表头挤出去的问题
2019/09/19 Javascript
Node.js 实现抢票小工具 &amp; 短信通知提醒功能
2019/10/22 Javascript
Preload基础使用方法详解
2020/02/03 Javascript
小程序中的箭头函数的具体使用
2020/06/19 Javascript
[26:24]完美副总裁、DOTA2负责人蔡玮专访:电竞如人生
2014/09/11 DOTA
python正则表达式去掉数字中的逗号(python正则匹配逗号)
2013/12/25 Python
python检测lvs real server状态
2014/01/22 Python
使用Python判断IP地址合法性的方法实例
2014/03/13 Python
python网络编程学习笔记(四):域名系统
2014/06/09 Python
Python基类函数的重载与调用实例分析
2015/01/12 Python
Python中字典创建、遍历、添加等实用操作技巧合集
2015/06/02 Python
python实现在字符串中查找子字符串的方法
2015/07/11 Python
PIL对上传到Django的图片进行处理并保存的实例
2019/08/07 Python
将tensorflow.Variable中的某些元素取出组成一个新的矩阵示例
2020/01/04 Python
Levi’s美国官网:美国著名的牛仔裤品牌
2016/08/19 全球购物
英国家电直销:Appliances Direct
2016/09/22 全球购物
旅游专业毕业生自荐书
2014/06/30 职场文书
2014领导班子四风剖析对照检查材料思想汇报
2014/09/20 职场文书
单位员工收入证明样本
2014/10/09 职场文书
2016年教师寒假学习心得体会
2015/10/09 职场文书
小学语文教师研修日志
2015/11/13 职场文书
JavaScript展开运算符和剩余运算符的区别详解
2022/02/18 Javascript
vue特效之翻牌动画
2022/04/20 Vue.js