基于JavaScript实现贪吃蛇游戏


Posted in Javascript onMarch 16, 2020

本文实例为大家分享了JavaScript实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下

1.结构

创建一个盒子box作为蛇的身体,当前盒子中只有一个子元素,代表此时蛇的长度为1.
在创建一个盒子food作为贪吃蛇的食物。

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

2.CSS

设置蛇和食物的样式,这里注意蛇和食物都是绝对定位。

<style>
 *{
  padding: 0px;
  margin: 0px;
 }
 #box div{
  width: 30px;
  height: 30px;
  box-sizing: border-box;
  background: green;
  border: 1px solid black;
  position: absolute;
 }
 #food{
  width: 30px;
  height: 30px;
  background: brown;
  position: absolute;
 }
 </style>

3.脚本

获取蛇的身体和每一个子元素

var box = document.getElementById("box");
var boxs = document.getElementById("box").children;

定义蛇头的位置

var snackX = 0;
var snackY = 0;

获取屏幕宽度和高度,以此来设定墙的边界,以限制蛇的移动范围。

var cw = document.documentElement.clientWidth;
 var ch = document.documentElement.clientHeight;
 var minsnackX = 0;
 var maxsnackX = Math.floor(cw / boxs[0].offsetWidth)*boxs[0].offsetWidth;
 var minsnackY = 0;
 var maxsnackY = Math.floor(ch / boxs[0].offsetHeight)*boxs[0].offsetHeight;

定义初始的移动方向。

var turn = "right";

获取食物元素,并设置食物的位置坐标。

var foodele = document.getElementById("food");
 var foodX,foodY;

蛇的初始化

for(var i = 0; i <6 ; i++){
  box.appendChild(boxs[0].cloneNode(true));
 }

刷新食物

function food(){
 //此处的坐标要先获取页面最大支持的蛇身体的块数,然后在块数中随机,然后乘以块数的大小,
 //因为蛇的移动每一步都是固定的,想要判定食物和蛇头重合就必须坐标是整块的倍数。
  foodX = parseInt( Math.random()*Math.floor(cw / boxs[0].offsetWidth))*boxs[0].offsetWidth;
  foodY = parseInt( Math.random()*Math.floor(ch / boxs[0].offsetHeight))*boxs[0].offsetHeight;
  //判定当食物的产生位置和蛇的任何一个位置重合时就重新生成食物。
  for(var i = 0;i<boxs.length;i++){
   if(foodX + "px" === boxs[i].style.left && foodY + "px" === boxs[i].style.top){
    food();
   }
  }
  foodele.style.left = foodX + "px";
  foodele.style.top = foodY + "px";
 }

调用food()方法 生成第一个食物

food();

设置定时器 每次执行一次蛇的运行方法

var timer = setInterval(function(){
  snackMOve();
 },150)

封装一个蛇的运动方法

//移动和判定边界
 function snackMOve(){
//此处为判定方向 根据判定的方向,向改方向前进一个方块
  switch(turn){
   case "right":snackX +=30;break;
   case "left":snackX -=30;break;
   case "bottom":snackY +=30;break;
   case "top":snackY -=30;break;
  }
  //如果蛇越过了墙就从另一端出现
  if(snackX > maxsnackX){
   snackX = 0;
  }
  if(snackX < minsnackX){
   snackX = maxsnackX;
  }
  if(snackY > maxsnackY){
   snackY = 0;
  } 
  if(snackY < minsnackY){
   snackY = maxsnackY;
  }
  //从最后一个开始,每个元素跟随上一个元素的位置
  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[0].style.left = snackX + "px";
  boxs[0].style.top = snackY + "px" ;


  //判定吃到食物 就长大和刷新
  //当蛇头位置移动之后与食物重合 那么刷新食物,并且在蛇的身体中插入一个克隆的元素,相当于长度+1
  if(snackX === foodX && snackY === foodY){
   food();
   box.appendChild(boxs[0].cloneNode(true));
  }else{
  //判定撞死 
  //当蛇头与身体中的任何一个元素重合,那么判定结束游戏,停止定时器
   for(var i = 1;i<boxs.length;i++){
    if(snackX + "px" === boxs[i].style.left && snackY + "px" === boxs[i].style.top){
     clearInterval(timer);
     alert("失败");
    }
   }
  }
 }

蛇的运动方向

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

全部代码

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
 <style>
 *{
  padding: 0px;
  margin: 0px;
 }
 #box div{
  width: 30px;
  height: 30px;
  box-sizing: border-box;
  background: green;
  border: 1px solid black;
  position: absolute;
 }
 #food{
  width: 30px;
  height: 30px;
  background: brown;
  position: absolute;
 }
 </style>
</head>
<body>
 <div id="box">
  <div></div>
 </div>
 <div id="food"></div>
 <script>
  var box = document.getElementById("box");
  var boxs = document.getElementById("box").children;
  var snackX = 0;
  var snackY = 0;
  var cw = document.documentElement.clientWidth;
  var ch = document.documentElement.clientHeight;
  var minsnackX = 0;
  var maxsnackX = Math.floor(cw / boxs[0].offsetWidth)*boxs[0].offsetWidth;
  var minsnackY = 0;
  var maxsnackY = Math.floor(ch / boxs[0].offsetHeight)*boxs[0].offsetHeight;
  var turn = "right";
  var foodele = document.getElementById("food");
  var foodX,foodY;

  for(var i = 0; i <6 ; i++){
   box.appendChild(boxs[0].cloneNode(true));
  }


  //随机食物
  function food(){
   foodX = parseInt( Math.random()*Math.floor(cw / boxs[0].offsetWidth))*boxs[0].offsetWidth;
   foodY = parseInt( Math.random()*Math.floor(ch / boxs[0].offsetHeight))*boxs[0].offsetHeight;
   for(var i = 0;i<boxs.length;i++){
    if(foodX + "px" === boxs[i].style.left && foodY + "px" === boxs[i].style.top){
     food();
    }
   }
   foodele.style.left = foodX + "px";
   foodele.style.top = foodY + "px";
  }
  food();

  //设置定时器 移动
  var timer = setInterval(function(){
   snackMOve();
  },150)


  //移动和判定边界
  function snackMOve(){
   switch(turn){
    case "right":snackX +=30;break;
    case "left":snackX -=30;break;
    case "bottom":snackY +=30;break;
    case "top":snackY -=30;break;
   }
   //根据边界归零
   if(snackX > maxsnackX){
    snackX = 0;
   }
   if(snackX < minsnackX){
    snackX = maxsnackX;
   }
   if(snackY > maxsnackY){
    snackY = 0;
   } 
   if(snackY < minsnackY){
    snackY = maxsnackY;
   }
   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[0].style.left = snackX + "px";
   boxs[0].style.top = snackY + "px" ;


   //判定吃到食物 就长大和刷新
   if(snackX === foodX && snackY === foodY){
    food();
    box.appendChild(boxs[0].cloneNode(true));
   }else{
   //判定撞死 暂停计时器 刷新
    for(var i = 1;i<boxs.length;i++){
     // console.log(boxs[i].style.left);
     if(snackX + "px" === boxs[i].style.left && snackY + "px" === boxs[i].style.top){
      clearInterval(timer);
      alert("失败");
      // console.log(1)
     }
    }
   }
  }


  //方向
  document.onkeydown = function(eve){
   var e = eve||event;
   var keyCode = e.keyCode||e.which;
   switch(keyCode){
    case 37:if(turn === "right"){break;}turn = "left";break;
    case 38:if(turn === "bottom"){break;}turn = "top";break;
    case 39:if(turn === "left"){break;}turn = "right";break;
    case 40:if(turn === "top"){break;}turn = "bottom";break;
   }  
  }
 </script>
</body>
</html>

总结

贪吃蛇的思路主要是有以下几个部分

1.食物的随机出现(不能随机在蛇身上)
2.定时器控制蛇的移动
3.墙的判定
4.蛇的运动逻辑
5.运动方向的判定
6.吃到食物的判定
7.蛇头与身体的判定(即游戏结束的判定)

小编还为大家准备了精彩的专题:javascript经典小游戏汇总

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

Javascript 相关文章推荐
javascript 多种搜索引擎集成的页面实现代码
Jan 02 Javascript
js如何实现设计模式中的模板方法
Jul 23 Javascript
jquery中animate动画积累的解决方法
Oct 05 Javascript
ExtJS4中使用mixins实现多继承示例
Dec 03 Javascript
jQuery 实现自动填充邮箱功能(带下拉提示)
Oct 14 Javascript
jQuery编程中的一些核心方法简介
Aug 14 Javascript
拥有一个属于自己的javascript表单验证插件
Mar 24 Javascript
jquery实现页面加载效果
Feb 21 Javascript
node.js自动上传ftp的脚本分享
Jun 16 Javascript
详解一个小实例理解js原型和继承
Apr 24 Javascript
js 判断当前时间是否处于某个一个时间段内
Sep 19 Javascript
通过js实现压缩图片上传功能
Feb 25 Javascript
原生js实现的金山打字小游戏(实例代码详解)
Mar 16 #Javascript
JavaScript实现拖拽效果
Mar 16 #Javascript
js实现点赞效果
Mar 16 #Javascript
Javascript Web Worker使用过程解析
Mar 16 #Javascript
Javascript ParentNode和ChildNode接口原理解析
Mar 16 #Javascript
JS手写一个自定义Promise操作示例
Mar 16 #Javascript
JS函数参数的传递与同名参数实例分析
Mar 16 #Javascript
You might like
PHP 开发环境配置(Zend Server安装)
2010/04/28 PHP
PHP删除HTMl标签的三种解决方法
2013/06/30 PHP
php $_SERVER windows系统与linux系统下的区别说明
2014/02/14 PHP
PHP查询快递信息的方法
2015/03/07 PHP
PHP 接入支付宝即时到账功能
2016/09/18 PHP
如何直接访问php实例对象中的private属性详解
2017/10/12 PHP
jQuery结合ajax实现动态加载文本内容
2015/05/19 Javascript
javascript实时显示当天日期的方法
2015/05/20 Javascript
JSON 必知必会 观后记
2016/10/27 Javascript
关于axios返回空对象的问题解决
2017/04/04 Javascript
Node.js 8 中的 util.promisify的详解
2017/06/12 Javascript
javascript用rem来做响应式开发
2018/01/13 Javascript
Vue精简版风格概述
2018/01/30 Javascript
深入理解JS中Number(),parseInt(),parseFloat()三者比较
2018/08/24 Javascript
详解JavaScript执行模型
2020/11/16 Javascript
JS模拟实现京东快递单号查询
2020/11/30 Javascript
[01:45]DOTA2众星出演!DSPL刀塔次级职业联赛宣传片
2014/11/21 DOTA
python调用机器喇叭发出蜂鸣声(Beep)的方法
2015/03/23 Python
python创建临时文件夹的方法
2015/07/06 Python
详解Django框架中用context来解析模板的方法
2015/07/20 Python
python中range()与xrange()用法分析
2016/09/21 Python
python 如何快速找出两个电子表中数据的差异
2017/05/26 Python
python Opencv将图片转为字符画
2021/02/19 Python
Python使用pip安装pySerial串口通讯模块
2018/04/20 Python
对Python 多线程统计所有csv文件的行数方法详解
2019/02/12 Python
使用Python实现 学生学籍管理系统
2019/11/26 Python
使用Python解析Chrome浏览器书签的示例
2020/11/13 Python
Python 图片处理库exifread详解
2021/02/25 Python
精灵市场:Pixie Market
2019/06/18 全球购物
匈牙利超级网上商店和优惠:Alza.hu
2019/12/17 全球购物
到底Java是如何传递参数的?是by value或by reference?
2012/07/13 面试题
后备干部培训方案
2014/05/22 职场文书
社区娱乐活动方案
2014/08/21 职场文书
学习优秀党员杨宗兴先进事迹材料思想汇报
2014/09/14 职场文书
2014年校长工作总结
2014/12/11 职场文书
能让Python提速超40倍的神器Cython详解
2021/06/24 Python