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 相关文章推荐
clientX,pageX,offsetX,x,layerX,screenX,offsetLeft区别分析
Mar 12 Javascript
js实现div弹出层的方法
Nov 20 Javascript
快速学习jQuery插件 Cookie插件使用方法
Dec 01 Javascript
js简单倒计时实现代码
Apr 30 Javascript
深入学习Bootstrap表单
Dec 13 Javascript
使用openSpeDiv方法实现Ecshop登录弹窗框效果
Mar 13 Javascript
微信小程序 中wx.chooseAddress(OBJECT)实例详解
Mar 31 Javascript
JavaScript中 DOM操作方法小结
Apr 25 Javascript
深入理解vue $refs的基本用法
Jul 13 Javascript
不得不知的ES6小技巧
Jul 28 Javascript
生产制造追溯系统之再说条码打印
Jun 03 Javascript
weui中的picker使用js进行动态绑定数据问题
Nov 06 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(7) php 字符串相关应用
2010/03/05 PHP
PHP中10个不常见却非常有用的函数
2010/03/21 PHP
PHP数据类型之整数类型、浮点数的介绍
2013/04/28 PHP
php使用正则过滤js脚本代码实例
2014/05/10 PHP
从数组中随机取x条不重复数据的JS代码
2013/12/24 Javascript
jQuery实现单击弹出Div层窗口效果(可关闭可拖动)
2015/09/19 Javascript
jQuery+Ajax实现无刷新分页
2015/10/30 Javascript
JavaScript实现搜索框的自动完成功能(一)
2016/02/25 Javascript
使用 jQuery.ajax 上传带文件的表单遇到的问题
2016/10/31 Javascript
第一次接触神奇的前端框架vue.js
2016/12/01 Javascript
深入理解JavaScript中的尾调用(Tail Call)
2017/02/07 Javascript
浅谈js停止事件冒泡 阻止浏览器的默认行为(阻止超连接 #)
2017/02/08 Javascript
js 监控iframe URL的变化实例代码
2017/07/12 Javascript
ES7中利用Await减少回调嵌套的方法详解
2017/11/01 Javascript
JS实现生成由字母与数字组合的随机字符串功能详解
2018/05/25 Javascript
基于vue.js中关于下拉框的值默认及绑定问题
2018/08/22 Javascript
vue.js表单验证插件(vee-validate)的使用教程详解
2019/05/23 Javascript
JavaScript this在函数中的指向及实例详解
2019/10/14 Javascript
何时/使用 Vue3 render 函数的教程详解
2020/07/25 Javascript
浅谈pandas中Dataframe的查询方法([], loc, iloc, at, iat, ix)
2018/04/10 Python
python 寻找list中最大元素对应的索引方法
2018/06/28 Python
python版opencv摄像头人脸实时检测方法
2018/08/03 Python
python爬虫神器Pyppeteer入门及使用
2019/07/13 Python
利用Python实现手机短信监控通知的方法
2019/07/22 Python
python错误调试及单元文档测试过程解析
2019/12/19 Python
Html5上传图片 移动端、PC端通用代码
2016/06/08 HTML / CSS
html5的websockets全双工通信详解学习示例
2014/02/26 HTML / CSS
英国人最爱的饰品网站:Accessorize
2016/08/22 全球购物
如何强制垃圾回收
2015/10/06 面试题
什么是用户模式(User Mode)与内核模式(Kernel Mode) ?
2015/09/07 面试题
旅游管理专业学生求职信
2013/09/28 职场文书
测试工程师岗位职责
2013/11/28 职场文书
电子商务助理求职自荐信
2014/04/10 职场文书
社区工作者演讲稿
2014/05/23 职场文书
《巨人的花园》教学反思
2016/02/19 职场文书
MySQL query_cache_type 参数与使用详解
2021/07/01 MySQL