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 相关文章推荐
Javascript算符的优先级介绍
Mar 20 Javascript
js判断IE浏览器版本过低示例代码
Nov 22 Javascript
jQuery插件实现适用于移动端的地址选择器
Feb 18 Javascript
SelecT下拉框选中和取值的解决方法
Nov 22 Javascript
谈谈第三方App接入微信登录 解读
Dec 27 Javascript
jQuery与js实现颜色渐变的方法
Dec 30 Javascript
Input文本框随着输入内容多少自动延伸的实现
Feb 15 Javascript
JS实现控制图片显示大小的方法【图片等比例缩放功能】
Feb 18 Javascript
微信小程序对接七牛云存储的方法
Jul 30 Javascript
Vue官方文档梳理之全局配置
Nov 22 Javascript
vue监听键盘事件的快捷方法【推荐】
Jul 11 Javascript
node+multer实现图片上传的示例代码
Feb 18 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 ADODB使用方法集锦
2008/03/25 PHP
推荐10个提供免费PHP脚本下载的网站
2014/12/31 PHP
PHP连接access数据库
2015/03/27 PHP
PHP实现按之字形顺序打印二叉树的方法
2018/01/16 PHP
ExtJs 3.1 XmlTreeLoader Example Error
2010/02/09 Javascript
JavaScript日历实现代码
2010/09/12 Javascript
JavaScript高级程序设计 阅读笔记(十七) js事件
2012/08/14 Javascript
js模仿jquery的写法示例代码
2013/06/16 Javascript
使用javascript控制cookie显示和隐藏背景图
2014/02/12 Javascript
15个jquery常用方法、小技巧分享
2015/01/13 Javascript
深入分析javascript中的错误处理机制
2016/07/17 Javascript
利用python分析access日志的方法
2016/10/26 Javascript
vue2.0使用Sortable.js实现的拖拽功能示例
2017/02/21 Javascript
深入理解vue中的$set
2017/06/01 Javascript
element ui table 增加筛选的方法示例
2018/11/02 Javascript
vue中eslintrc.js配置最详细介绍
2018/12/21 Javascript
JavaScript代码调试方法实例小结
2019/01/05 Javascript
微信小程序中button去除默认的边框实例代码
2019/08/01 Javascript
深入解读VUE中的异步渲染的实现
2020/06/19 Javascript
Vue实现图书管理小案例
2020/12/03 Vue.js
使用C++扩展Python的功能详解
2018/01/12 Python
python 输出上个月的月末日期实例
2018/04/11 Python
Python实现查看系统启动项功能示例
2018/05/10 Python
css3针对移动端卡顿问题的解决(动画性能优化)
2020/02/14 HTML / CSS
浅析HTML5:'data-'属性的作用
2018/01/23 HTML / CSS
美国第二大连锁书店:Books-A-Million
2017/12/28 全球购物
会计出纳岗位职责
2013/12/25 职场文书
创建服务型党组织实施方案
2014/02/25 职场文书
小学清明节活动方案
2014/03/08 职场文书
党员先进事迹材料
2014/12/19 职场文书
化验室岗位职责
2015/02/14 职场文书
防卫过当辩护词
2015/05/21 职场文书
五星级酒店宣传口号
2015/12/25 职场文书
导游词之黄果树瀑布
2019/09/20 职场文书
爱心捐款倡议书:点燃希望,传递温暖
2019/11/04 职场文书
Python 第三方库 openpyxl 的安装过程
2022/12/24 Python