如何基于javascript实现贪吃蛇游戏


Posted in Javascript onFebruary 09, 2020

这篇文章主要介绍了如何基于javascript实现贪吃蛇游戏,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

html代码:

<div class="content">
  <div class="btn startBtn">       <!-- 开始按钮 -->  
    <button type="button"></button>
  </div>
  <div class="btn stopBtn">        <!-- 暂停按钮 -->
    <button type="button"></button>
  </div>
  <div id="snakeWrap"></div>     <!-- 主题内容 -->
</div>

css代码:

* {
  margin: 0;
  padding: 0;
}
body {
  background-color: #565F65;
  width: 100%;
  height: 10vh;
  overflow: hidden;
}

.content {
  width: 500px;
  height: 500px;
  position: absolute;
  top: 50%;
  left: 50%; 
  margin-top: -250px;
  margin-left: -250px;
  background-color: #565F65;
  border: 10px solid #E7E7E7;
  box-shadow: inset 0px 0px 5px 2px #000;
}
.btn {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background-color: rgba(0, 0, 0, .3);  /*游戏未开始时和暂停时的遮罩*/
  z-index: 2;
}
.btn button {
  background: none;
  border: none;
  background-size: 100% 100%;
  cursor: pointer;
  outline: none;
  position: absolute;
  left: 50%;
  top: 50%;
}
.startBtn button{
  width: 170px;
  height: 80px;
  background-image: url(img/startbtn.png);
  margin-top: -40px;
  margin-left: -85px;
}
.stopBtn {
  display: none;
}
.stopBtn button{
  width: 70px;
  height: 70px;
  background-image: url(img/stopbtn.png);
  margin-top: -35px;
  margin-left: -35px;
}

#snakeWrap {
  width: 500px;
  height: 500px;
  position: relative;
}
.snakeHead { /*蛇头样式*/
  background-color: aqua;
  border-radius: 50%;
}
.snakeBody { /*蛇身样式*/      
  background-color: navajowhite;
  border-radius: 50%;
}
.food {  /*食物样式*/
  background-image: url(img/food.png);
  background-size: cover;
}

javascript 代码:

var sw = 20,  //一个方块的宽
   sh = 20,  //一个方块的高
    tr = 25,  //行数
    td = 25;  //列数
var snake = null,  //蛇的实例
    food = null,  //食物的实例
    game = null;  //游戏的实例
function Square(x, y, classname) {
  this.x = x * sw;     //方块实际的位置
  this.y = y * sh;     //方块实际的位置
  this.class = classname;
  
  this.viewContent = document.createElement('div');  //方块对应的DOM元素
  this.viewContent.className = this.class;
  this.parent = document.getElementById('snakeWrap'); //方块的父级
}

Square.prototype.create = function() {  //创建方块 DOM,并添加到页面里
  this.viewContent.style.position = 'absolute';
  this.viewContent.style.width = sw + 'px';
  this.viewContent.style.height = sh + 'px';
  this.viewContent.style.left = this.x + 'px';
  this.viewContent.style.top = this.y + 'px';
  
  this.parent.appendChild(this.viewContent);
};

Square.prototype.remove = function() {
  this.parent.removeChild(this.viewContent);
}

//蛇
function Snake() {
  this.head = null;  //存一下蛇头的信息
  this.tail = null;  //存一下蛇尾的信息
  this.pos = [];   //存储蛇身上的每一个方块的位置,二维数组
  
  this.directionNum = {  //存储蛇走的方向,用一个对象来表示
    left : {
      x : -1,
      y : 0,
      rotate : 180
    },
    right : {
      x : 1,
      y : 0,
      rotate : 0
    },
    up : {
      x : 0,
      y : -1,
      rotate : -90
    },
    down : {
      x : 0,
      y : 1,
      rotate : 90
    }
  }
}

Snake.prototype.init = function() {
  //创建蛇头
  var snakeHead = new Square(2, 0, 'snakeHead');
  snakeHead.create();
  this.head = snakeHead;    // 存储蛇头信息
  this.pos.push([2, 0]);    //把蛇头的位置存起来
  
  //创建蛇身体
  var snakeBody1 = new Square(1, 0, 'snakeBody');
  snakeBody1.create();
  this.pos.push([1, 0]);    //把蛇身1的位置存起来
  
  var snakeBody2 = new Square(0, 0, 'snakeBody');
  snakeBody2.create();
  this.tail = snakeBody2;    //把蛇尾的信息存起来
  this.pos.push([0, 0]);    //把蛇身1的位置存起来
  
  //让蛇头蛇身形成链表关系
  snakeHead.last = null;
  snakeHead.next = snakeBody1;
  
  snakeBody1.last = snakeHead;
  snakeBody1.next = snakeBody2;
  
  snakeBody2.last = snakeBody1;
  snakeBody2.next = null;
  
  //给蛇添加一条属性,用来表示蛇走的方向
  this.direction = this.directionNum.right; //默认让蛇往右走
  
}

//这个方法用来获取蛇头的下一个位置对应的元素, 要根据元素做不同的事情
Snake.prototype.getNextPos = function() {
  var nextPos = [             //蛇头要走的下一个点的坐标
    this.head.x/sw + this.direction.x,
    this.head.y/sh + this.direction.y
  ];
  
  //下一个点是自己,代表撞到了自己,游戏结束
  var selfCollind = false;   //是否撞到自己
  this.pos.forEach(function(value) {
    if(value[0] == nextPos[0] && value[1] == nextPos[1]) {
      //如果数组中的两个数据都相等,就说明下一个点在蛇身上里面能找到,代表撞到自己了
      selfCollind = true;
    }
  });
  if(selfCollind) {
    console.log('撞到自己了!');
    
    this.strategies.die.call(this);
    
    return;
  }
  
  //下一个点是墙,游戏结束
  if(nextPos[0] < 0 || nextPos[1] < 0 || nextPos[0] > td - 1 || nextPos[1] > tr - 1) {
    console.log('撞墙了!');
    
    this.strategies.die.call(this);
    
    return;
  }
  //下一个点是食物,吃
  if(food && food.pos[0] == nextPos[0] && food.pos[1] == nextPos[1]) {
    //如果这个条件成立说明现在蛇头要走的下一个点是食物的那个点
    console.log('撞到食物了了!');
    this.strategies.eat.call(this);
    return;
  }
  //下一个点什么都不是,走
  this.strategies.move.call(this);
};

//处理碰撞后要做的事 
Snake.prototype.strategies = {
  move : function(format) {  //这个参数用于决定要不要删除最后一个方块(蛇尾), 当传了这个参数后就表示要做的事情是吃
    //创建新身体(在蛇头位置)
    var newBody = new Square(this.head.x/sw, this.head.y/sh, 'snakeBody');
    //更新链表关系
    newBody.next = this.head.next;
    newBody.next.last = newBody;
    newBody.last = null;
    
    
    this.head.remove();  //旧舌头从原来的位置删除
    newBody.create();
    
    //创建一个新蛇头(蛇头下一个要走到的点)
    var newHead = new Square(this.head.x/sw + this.direction.x, this.head.y/sh + this.direction.y, 'snakeHead')
    //更新链表关系
    newHead.next = newBody;
    newHead.last = null;
    newBody.last = newHead;
    newHead.viewContent.style.transform = 'rotate('+this.direction.rotate+'deg)';
    newHead.create();
    
    
    //蛇身上每一个方块的坐标也要更新
    this.pos.splice(0,0, [this.head.x/sw + this.direction.x, this.head.y/sh + this.direction.y]);
    this.head = newHead;   //还要把this.head的信息更新一下
    
    if(!format) {  //如何format 的值为 false, 表示需要删除(除了吃之外的操作)
      this.tail.remove();
      this.tail = this.tail.last;
      
      this.pos.pop();
    }
    
  },
  eat : function() {
    this.strategies.move.call(this, true);
    createFood();
    game.score ++;
  },
  die : function() {
    game.over();
  }
}

snake = new Snake();

//创建食物
function createFood() {
  //食物小方块的随机坐标
  var x = null;
  var y = null;
  
  var include = true;  //循环跳出的条件, true表示食物的坐标在蛇身上(需要继续循环),false表示食物坐标不在蛇身上(不循环了)
  while(include) {
    x = Math.round(Math.random() * (td - 1)); //0-29
    y = Math.round(Math.random() * (tr - 1));
    
    snake.pos.forEach(function(value) {
      if(x != value[0] && y != value[1]) {
        //这个条件成立说明现在随机出来的这个坐标,在蛇身上并没有找到
        include = false;
      }
    });
    
  }
  //生成食物
  food = new Square(x, y, 'food');
  food.pos = [x,y]; //存储一下生成食物的坐标,用于跟蛇头要走的下一个点作对比
  var foodDom = document.querySelector('.food');
  if(foodDom) {
    foodDom.style.left = x*sw + 'px';
    foodDom.style.top = y*sh + 'px';
  }else {
    food.create();
  }
}



//创建游戏逻辑
function Game() {
  this.timer = null;
  this.score = 0;
  this.speed = 200;
}
Game.prototype.init = function() {
  snake.init();
  snake.getNextPos();
  createFood();
  
  document.onkeydown = function(ev) {  //用户按下方向键触发事件
    if(ev.which == 37 && snake.direction != snake.directionNum.right) { 
      //用户按下左键是,蛇不能是往右走
      snake.direction = snake.directionNum.left;
    }else if(ev.which == 38 && snake.direction != snake.directionNum.dowm) {
      snake.direction = snake.directionNum.up;
    }else if(ev.which == 39 && snake.direction != snake.directionNum.left) {
      snake.direction = snake.directionNum.right;
    }else if(ev.which == 40 && snake.direction != snake.directionNum.up) {
      snake.direction = snake.directionNum.down;
    }
  }
  
  this.start();
}

Game.prototype.start = function() { //开始游戏
  this.timer = setInterval(function() {
    snake.getNextPos();
    
  }, this.speed);
}
Game.prototype.pause = function() {
  clearInterval(this.timer);
}
Game.prototype.over = function() { //开始游戏
  clearInterval(this.timer);
  alert('你的得分为' + this.score);
  
  //游戏回到最初的状态
  var snakeWrap = document.getElementById('snakeWrap');
  snakeWrap.innerHTML = '';
  snake = new Snake();
  game = new Game();
  var startBtnWrap = document.querySelector('.startBtn');
  startBtnWrap.style.display = 'block'; 
}
//开启游戏
game = new Game();
var startBtn = document.querySelector('.startBtn button');
startBtn.onclick = function() {
  startBtn.parentNode.style.display = 'none';
  game.init();
};


//暂停
var snakeWrap = document.getElementById('snakeWrap');
var puseBtn = document.querySelector('.stopBtn button')
snakeWrap.onclick = function() {
  game.pause();
  puseBtn.parentNode.style.display = 'block';
}

puseBtn.onclick =function() {
  game.start();
  puseBtn.parentNode.style.display = 'none';
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
写JQuery插件的基本知识
Nov 25 Javascript
js弹窗返回值详解(window.open方式)
Jan 11 Javascript
js中通过父级进行查找定位元素
Jun 15 Javascript
JS实现自适应高度表单文本框的方法
Feb 25 Javascript
JavaScript实现表格快速变色效果代码
Aug 19 Javascript
jquery.cookie实现的客户端购物车操作实例
Dec 24 Javascript
vue实现todolist单页面应用
Apr 11 Javascript
Agularjs妙用双向数据绑定实现手风琴效果
May 26 Javascript
详解extract-text-webpack-plugin 的使用及安装
Jun 12 Javascript
js中split()方法得到的数组长度问题
Jul 19 Javascript
ExtJs使用自定义插件动态保存表头配置(隐藏或显示)
Sep 25 Javascript
详解JavaScript中精度失准问题及解决方法
Feb 04 Javascript
javascript浅层克隆、深度克隆对比及实例解析
Feb 09 #Javascript
通过javascript实现扫雷游戏代码实例
Feb 09 #Javascript
jQuery实现简单聊天室
Feb 08 #jQuery
jquery实现点击弹出对话框
Feb 08 #jQuery
jQuery实现简易聊天框
Feb 08 #jQuery
jquery添加div实现消息聊天框
Feb 08 #jQuery
js实现聊天对话框
Feb 08 #Javascript
You might like
DOM XPATH获取img src值的query
2013/09/23 PHP
php防止伪造数据从地址栏URL提交的方法
2014/08/24 PHP
php基于CodeIgniter实现图片上传、剪切功能
2016/05/14 PHP
thinkphp3.2框架中where条件查询用法总结
2019/08/13 PHP
JQuery的Alert消息框插件使用介绍
2010/10/09 Javascript
javascript操纵OGNL标签示例代码
2014/06/16 Javascript
jquery text()方法取标签中的文本
2014/07/25 Javascript
JavaScript中的逻辑判断符&amp;&amp;、||与!介绍
2014/12/31 Javascript
JS弹出可拖拽可关闭的div层完整实例
2015/02/13 Javascript
JS实现的不规则TAB选项卡效果代码
2015/09/18 Javascript
Js的Array数组对象详解
2016/02/22 Javascript
原生js实现中奖信息无间隙滚动效果
2017/01/18 Javascript
jquery实现图片上传前本地预览
2017/04/28 jQuery
微信小程序 地图map实例详解
2017/06/07 Javascript
利用纯js + transition动画实现移动端web轮播图详解
2017/09/10 Javascript
微信小程序上传图片功能(附后端代码)
2020/06/19 Javascript
vue调试工具vue-devtools安装及使用方法
2018/11/07 Javascript
11个Javascript小技巧帮你提升代码质量(小结)
2020/12/28 Javascript
python安装oracle扩展及数据库连接方法
2017/02/21 Python
python实现感知器
2017/12/19 Python
浅析Python 读取图像文件的性能对比
2019/03/07 Python
pymongo中group by的操作方法教程
2019/03/22 Python
如何修复使用 Python ORM 工具 SQLAlchemy 时的常见陷阱
2019/11/19 Python
使用python实现微信小程序自动签到功能
2020/04/27 Python
大都会艺术博物馆商店:The Met Store
2018/06/22 全球购物
Omio荷兰:预订火车、巴士和机票
2018/11/04 全球购物
乌克兰排名第一的在线旅游超市:Farvater.Travel
2020/01/02 全球购物
党的群众路线教育实践活动对照检查材料思想汇报(党员篇)
2014/09/25 职场文书
离婚财产处理协议书
2014/09/30 职场文书
丧事答谢词
2015/01/05 职场文书
市场总监岗位职责
2015/02/11 职场文书
2015年电话销售工作总结范文
2015/04/20 职场文书
幼儿园开学温馨提示
2015/07/15 职场文书
2015中秋节晚会开场白
2015/07/30 职场文书
python实现三阶魔方还原的示例代码
2021/04/28 Python
HTTP中的Content-type详解
2022/01/18 HTML / CSS