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使整个div区域可以点击的方法
Jun 24 Javascript
Jquery常用的方法汇总
Sep 01 Javascript
jQuery中trigger()与bind()用法分析
Dec 18 Javascript
JS实现点击登录弹出窗口同时背景色渐变动画效果
Mar 25 Javascript
bootstrap选项卡扩展功能详解
Jun 14 Javascript
利用JS如何计算字符串所占字节数示例代码
Sep 13 Javascript
vue全局组件与局部组件使用方法详解
Mar 29 Javascript
vue-resource请求实现http登录拦截或者路由拦截的方法
Jul 11 Javascript
JavaScript函数apply()和call()用法与异同分析
Aug 10 Javascript
layui table设置前台过滤转义等方法
Aug 17 Javascript
如何基于JS截获动态代码
Dec 25 Javascript
vue 里面的 $forceUpdate() 强制实例重新渲染操作
Sep 21 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
jQuery+php实现ajax文件即时上传的详解
2013/06/17 PHP
在模板页面的js使用办法
2010/04/01 Javascript
jquery设置元素的readonly和disabled的写法
2013/09/22 Javascript
js获取事件源及触发该事件的对象
2013/10/24 Javascript
js 用CreateElement动态创建标签示例
2013/11/20 Javascript
深入理解JavaScript中的传值与传引用
2013/12/09 Javascript
JavaScript编程的10个实用小技巧
2014/04/18 Javascript
js 通过cookie实现刷新不变化树形菜单
2014/10/30 Javascript
node.js中的dns.getServers方法使用说明
2014/12/08 Javascript
node.js中的fs.utimesSync方法使用说明
2014/12/15 Javascript
在网页中插入百度地图的步骤详解
2016/12/02 Javascript
让微信小程序支持ES6中Promise特性的方法详解
2017/06/13 Javascript
VueJS 集成 Medium Editor的示例代码 (自定义编辑器按钮)
2017/08/24 Javascript
[js高手之路]设计模式系列课程-发布者,订阅者重构购物车的实例
2017/08/29 Javascript
p5.js入门教程之鼠标交互的示例
2018/03/16 Javascript
微信小程序实现留言板
2018/10/31 Javascript
解决Antd Table组件表头不对齐的问题
2020/10/27 Javascript
微信小程序实现modal弹出框遮罩层组件(可带文本框)
2020/12/20 Javascript
python基础教程之udp端口扫描
2014/02/10 Python
win10下Python3.6安装、配置以及pip安装包教程
2017/10/01 Python
Python使用Scrapy保存控制台信息到文本解析
2017/12/27 Python
python之super的使用小结
2018/08/13 Python
Python 使用类写装饰器的小技巧
2018/09/30 Python
Canvas绘制浮动球效果的示例
2017/12/29 HTML / CSS
德国最新街头服饰网上商店:BODYCHECK
2019/09/15 全球购物
沃尔玛旗下墨西哥超市:Bodega Aurrera
2020/11/13 全球购物
华为C++笔试题
2014/08/05 面试题
教师实习自我鉴定
2013/12/14 职场文书
运动会入场解说词300字
2014/01/25 职场文书
校园摄影活动策划方案
2014/02/05 职场文书
物理研修随笔感言
2014/02/14 职场文书
电台实习生求职信
2014/02/25 职场文书
自荐信模板大全
2015/03/27 职场文书
社区义诊通知
2015/04/24 职场文书
2015年政教主任工作总结
2015/07/23 职场文书
python使用pycharm安装pyqt5以及相关配置
2022/04/22 Python