JS实现贪吃蛇游戏


Posted in Javascript onNovember 15, 2019

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

html部分:

<!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">
 <link rel="stylesheet" href="./css/index.css" rel="external nofollow" >
 <title>贪吃蛇小游戏</title>
</head>
<body>
 <div class="content">
 <div class="btn startBtn"><button></button></div>
 <div class="btn pauseBtn"><button></button></div>
 <div id="snakeWrap">
 
 </div>
 </div>
 <script src="./js/index.js"></script>
</body>
</html>

css部分:

.content{
 width: 640px;
 height: 640px;
 margin: 50px auto;
 position: relative;
}
.btn{
 width: 100%;
 height: 100%;
 position: absolute;
 left: 0;
 top: 0;
 background-color: rgba(0,0,0,0);
 z-index: 1;
}
.btn button{
 background: none;
 border:none;
 background-size: 100% 100%;
 cursor: pointer;
 outline: none;
 position: absolute;
 left: 50%;
 top: 50%;
}
.startBtn button{
 width: 200px;
 height: 150px;
 background-image: url('../images/btn1.gif');
 margin-left: -100px;
 margin-top: -75px;
}
.pauseBtn{
 display: none;
}
.pauseBtn button{
 width: 70px;
 height: 70px;
 background-image: url('../images/btn4.png');
 margin-left: -35px;
 margin-top: -35px;
}
#snakeWrap{
 position: relative;
 width: 600px;
 height: 600px;
 background: #FCE4EC;
 border: 20px solid #F8BBD0;
}
.snakeHead{
 background-image: url('../images/snake.png');
 background-size: cover;
}
.snakeBody{
 background-color: #9CCC65;
 border-radius: 50%;
}
.food{
 background: url('../images/food2.png') no-repeat;
 background-size: 100% 100%;
}

js部分:

var sw = 20, // 一个方块的宽度
 sh = 20, // 高度
 tr = 30, // 行数
 td = 30; // 列数

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');
 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 selfCollied = false; //是否撞到了自己
 this.pos.forEach(function(value) {
 if(value[0]==nextPos[0] && value[1]==nextPos[1]){
 selfCollied = true;
 }
 });
 if(selfCollied){
 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){ // 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();
// snake.init();

// 创建食物
function createFood(){
 // 食物的随机坐标
 var x = null;
 var y = null;
 var include = true; // 循环跳出的条件,true表示食物坐标在蛇身上,false:表示不在
 while(include){
 x = Math.round(Math.random()*(td-1));
 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;

}
Game.prototype.init = function(){
 snake.init();
 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.down){
 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();
 
 },200);
}
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 pauseBtn = document.querySelector('.pauseBtn button');
snakeWrap.onclick = function() {
 game.pause();
 pauseBtn.parentNode.style.display='block';
}
pauseBtn.onclick = function() {
 game.start();
 pauseBtn.parentNode.style.display='none';
}

游戏截图:

JS实现贪吃蛇游戏

JS实现贪吃蛇游戏

更多关于Js游戏的精彩文章,请查看专题: 《JavaScript经典游戏 玩不停》

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

Javascript 相关文章推荐
基于jquery的表格排序
Sep 11 Javascript
JavaScript类型转换方法及需要注意的问题小结(挺全面)
Nov 11 Javascript
统计jQuery中各字符串出现次数的工具
May 03 Javascript
原生js实现淘宝首页点击按钮缓慢回到顶部效果
Apr 06 Javascript
JavaScript实现数字数组正序排列的方法
Apr 06 Javascript
详解JavaScript中的blink()方法的使用
Jun 08 Javascript
js前端面试题及答案整理(一)
Aug 26 Javascript
jquery实现全选、不选、反选的两种方法
Sep 06 Javascript
巧用数组制作图片切换js代码
Nov 29 Javascript
利用node.js制作命令行工具方法教程(一)
Jun 22 Javascript
详解vue使用vue-layer-mobile组件实现toast,loading效果
Aug 31 Javascript
vue远程加载sfc组件思路详解
Dec 25 Javascript
Layui表格监听行单双击事件讲解
Nov 14 #Javascript
layui table表格数据的新增,修改,删除,查询,双击获取行数据方式
Nov 14 #Javascript
解决Layui数据表格显示无数据提示的问题
Nov 14 #Javascript
layui写后台表格思路和赋值用法详解
Nov 14 #Javascript
Layui实现主窗口和Iframe层参数传递
Nov 14 #Javascript
layui 弹出层值回传解决方式
Nov 14 #Javascript
vue使用swiper.js重叠轮播组建样式
Nov 14 #Javascript
You might like
PHP安装问题
2006/10/09 PHP
php smarty函数扩展
2010/03/15 PHP
php示例详解Constructor Prototype Pattern 原型模式
2015/10/15 PHP
thinkPHP实现多字段模糊匹配查询的方法
2016/12/01 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
2017/09/16 PHP
使用js画图之画切线
2015/01/12 Javascript
JavaScript获取当前网页标题(title)的方法
2015/04/03 Javascript
JavaScript实现的SHA-1加密算法完整实例
2016/02/02 Javascript
node.js从数据库获取数据
2016/05/08 Javascript
vue router使用query和params传参的使用和区别
2017/11/13 Javascript
js数组去重的N种方法(小结)
2018/06/07 Javascript
关于js陀螺仪的理解分析
2019/04/11 Javascript
详解element-ui设置下拉选择切换必填和非必填
2019/06/17 Javascript
JS回调函数简单易懂的入门实例分析
2019/09/29 Javascript
Python通过正则表达式选取callback的方法
2015/07/18 Python
Python下载指定页面上图片的方法
2016/05/12 Python
详解Python各大聊天系统的屏蔽脏话功能原理
2016/12/01 Python
python开发简易版在线音乐播放器
2017/03/03 Python
Python中read()、readline()和readlines()三者间的区别和用法
2017/07/30 Python
python 日期操作类代码
2018/05/05 Python
Python爬虫包BeautifulSoup异常处理(二)
2018/06/17 Python
opencv python 图像轮廓/检测轮廓/绘制轮廓的方法
2019/07/03 Python
Python计算一个点到所有点的欧式距离实现方法
2019/07/04 Python
详解用python计算阶乘的几种方法
2019/08/14 Python
tensorboard显示空白的解决
2020/02/15 Python
Python的历史与优缺点整理
2020/05/26 Python
使用phonegap操作数据库的实现方法
2017/03/31 HTML / CSS
使用html5 canvas绘制圆环动效
2019/06/03 HTML / CSS
万豪国际住宅与别墅集团:Homes & Villas by Marriott International
2020/10/08 全球购物
企业演讲比赛主持词
2014/03/18 职场文书
青春励志演讲稿范文
2014/08/25 职场文书
高中教师个人工作总结
2015/02/10 职场文书
人生遥控器观后感
2015/06/11 职场文书
2016年清明节红领巾广播稿
2015/12/17 职场文书
Golang的继承模拟实例
2021/06/30 Golang
golang fmt格式“占位符”的实例用法详解
2021/07/04 Golang