javascript开发实现贪吃蛇游戏


Posted in Javascript onJuly 31, 2020

贪吃蛇的例子:

在此例子中,利用snake数组的第0个元素和direction对象中的x值和y值做加法,算出蛇的下一个位置。利用间隔函数,不停的修改类名来进行渲染操作,感觉是一个很灵活的例子。

style.css

*{
 margin: 0;
 padding: 0;
 box-sizing: border-box;
}

.page{
 width: 100vw;
 height: 100vh;
 position: absolute;
 left: 0;
 top: 0;
}
body{
 font-size: 0.16rem;
}
.startGame{
 /* display: none; */
 background: purple;
 display: flex; 
 justify-content: center;
 align-items: center;
}

.startBtn,.reStartBtn{
 width:2rem;
 height: 0.5rem;
 text-align: center;
 line-height: 0.5rem;
 background: deepskyblue;
 color: #fff;
}

.endGame{
 display: none;
 /* display:flex; */
 flex-direction: column;
 justify-content: center;
 align-items: center;
 background: lightsalmon;
}
.endGame h1{
 margin: 1rem 0;
 color: #fff;
}

.gaming{
 display: none;
 background: black;
 color: #fff;
 
}
.gaming .score{
 display: flex;
 justify-content: space-between;
 height: 0.5rem;
 align-items: center;
 width: 100vw;
 padding: 0 0.25rem;
}

.gaming .score .pauseBtn{
 
 width: 0.8rem;
 height: 0.3rem;
 line-height: 0.3rem;
 background: #999;
 text-align: center;
 
}

.gaming .mainGame{
 
 /* 15*20 */
 width: 3.45rem;
 height:4.6rem ;
 background: #555;
 margin: 0.3rem auto;
 display: flex;
 flex-wrap: wrap;
 border-top: 1px solid #ccc;
 border-left: 1px solid #ccc;
 box-sizing: content-box;
}
.gaming .mainGame .gezi{
 width: 0.23rem;
 height: 0.23rem;
 border-right: 1px solid #ccc;
 border-bottom: 1px solid #ccc;
}
.gaming .mainGame .gezi.snake{
 width: 0.23rem;
 height: 0.23rem;
 border-right: 1px solid #ccc;
 border-bottom: 1px solid #ccc;
 background-color: #fff;
}
.gaming .mainGame .gezi.food{
 width: 0.23rem;
 height: 0.23rem;
 border-right: 1px solid #ccc;
 border-bottom: 1px solid #ccc;
 /* background-color: orangered; */
}

.gaming .mainGame .gezi.food:before{
 width: 100%;
 height: 100%;
 content: "";
 display: block;
 background:yellow;
 animation: food 1s alternate infinite ;
 box-shadow: 0 0 10px #ffffcc;
}
.gaming .mainGame .gezi.food[data-food=redStar]:before{
 background:deeppink;
}
@keyframes food{
 from{
 transform: scale(1) rotate(0deg);
 }
 to{
 transform: scale(0.5) rotate(360deg);
 }
}


.gaming .mainGame .gezi.snake:before{
 content:"" ;
 display: block;
 
 width: 100%;
 height: 100%;
 background: #ccc;
 animation: snake 0.4s;
 box-sizing: border-box;
}
@keyframes snake{
 from{
 background: #fff;
 box-shadow:0 0 15px rgba(255,255,255,1);
 }
 to{
 background: #ccc;
 box-shadow:0 0 15px rgba(255,255,255,0.5);
 }
}

index.js主要实现了所有的贪吃蛇的页面的各种操作

var startBtn = document.querySelector(".startBtn")
var startPage = document.querySelector(".page.startGame")
var gamingPage = document.querySelector(".gaming")
var endGamePage = document.querySelector(".endGame")
var mainGame = document.querySelector(".mainGame")
var numDom = document.querySelector(".score .left .num")
var endGameScore = document.querySelector(".endGame .num")
var reStartBtn = document.querySelector('.reStartBtn');
var pauseBtn=document.querySelector(".pauseBtn");

var snake = [{x:0,y:1},{x:1,y:1},{x:2,y:1}];
var snakeFood = {
 x:10,y:10
}
//初始化得分
var score = 0;
var interId;
var ispaused=false;
//定义蛇运动的方向
//从右向左{x:-1,y:0}
//从左向右{x:1,y:0}
//从上到下{x:0,y:1}
//从下到上{x:0,y:-1}
var direction = {x:-1,y:0}


startBtn.onclick = function(){
 startPage.style.display = "none"
 gamingPage.style.display = "block"
 gameIng()
}


function renderGezi(){
 for(var i=0;i<20;i++){
 for(var j=0;j<15;j++){
 var gezi = document.createElement("div");
 gezi.className = "gezi";
 gezi.id = 'x'+j+'y'+i;
 mainGame.appendChild(gezi)
 }
 }
}


renderGezi()
//随机创建蛇,
function createSnake(){
 var randomX = parseInt(Math.random()*13)
 var randomY = parseInt(Math.random()*20)
 snake = [];
 for(var i= 0;i<3;i++){
 snake.push({x:randomX+i,y:randomY})
 }
 
}


function renderSnake(){
 snake.forEach(function(item,i){
 var snakeBody = document.querySelector("#x"+item.x+"y"+item.y);
 snakeBody.className = "gezi snake";
 })
}

//渲染食物
function renderFood(){
 var randomX = parseInt(Math.random()*15)
 var randomY = parseInt(Math.random()*20)
 
 var foodDiv = document.querySelector("#x"+randomX+"y"+randomY)
 if(foodDiv.className == "gezi snake"){
 renderFood()
 }else{
 foodDiv.className = "gezi food"
 }
 
}


createSnake()

renderFood()
renderSnake()

function gameIng(){
 interId = setInterval(function(){
 var headerX = snake[0].x + direction.x;
 var headerY = snake[0].y + direction.y;
 if(headerX<0){
 headerX = 14;
 }
 if(headerX>14){
 headerX = 0;
 }
 if(headerY<0){
 headerY = 19;
 }
 if(headerY>19){
 headerY = 0;
 }
 
 var snakeHeader = {x:headerX,y:headerY};
 isSnake(snakeHeader) 
 if(!isFood(snakeHeader)) {
 //将删除的蛇,找到相对应的dom,将其class类名修改成正常的gezi
 var snakeFooter = snake.pop()//返回删除的对象
 var snakeFooterDiv = document.querySelector("#x"+snakeFooter.x+"y"+snakeFooter.y);
 snakeFooterDiv.className = "gezi";
 }
 snake.unshift(snakeHeader)//在数组最前面加入
 
 
 
 renderSnake()
 },100)
}


function isSnake(snakeHeader){
 var newHeader = document.querySelector("#x"+snakeHeader.x+"y"+snakeHeader.y)
 if(newHeader.className == "gezi snake"){
 clearInterval(interId);
 gamingPage.style.display = "none"
 endGamePage.style.display = "flex"
 endGameScore.innerHTML = score;
 
 return true;
 }else{
 return false;
 }
}


function isFood(snakeHeader){
 var newHeader = document.querySelector("#x"+snakeHeader.x+"y"+snakeHeader.y)
 if(newHeader.className == "gezi food"){
 score ++;
 numDom.innerHTML = score;
 renderFood()
 return true;
 }else{
 return false;
 }
}

var body = document.body

body.addEventListener("keydown",function(e){
 console.log(e)
 //方向不能直接颠倒向上时原来不能是向下的。
 if(e.key == "ArrowUp"&&direction.y!=1){
 direction = {x:0,y:-1}
 }
 if(e.key=="ArrowRight"&&direction.x!=-1){
 direction = {x:1,y:0}
 }
 if(e.key == "ArrowDown"&&direction.y!=-1){
 direction = {x:0,y:1}
 }
 if(e.key=="ArrowLeft"&&direction.x!=1){
 direction = {x:-1,y:0}
 }
})

ylEvent.init(body);
body.addEvent("swiperLeft",function(){
 if(direction.x!=1){
 direction = {x:-1,y:0}
 }
})

body.addEvent("swiperRight",function(){
 if(direction.x!=-1){
 direction = {x:1,y:0}
 }
})

body.addEvent("swiperTop",function(){
 if(direction.y!=1){
 direction = {x:0,y:-1}
 }
})

body.addEvent("swiperBottom",function(){
 if(direction.y!=-1){
 direction = {x:0,y:1}
 }
})

reStartBtn.onclick = function(){
 location.reload();
}
pauseBtn.onclick=function(){
 if(ispaused){
 ispaused=false;
 gameIng();
 }else{
 ispaused=true;
 clearInterval(interId);
 }
}

js辅助式响应.js

(function(){
function xys(){
 var userAgent=navigator.userAgent
 var html=document.querySelector("html");
 //userAgent.indexOf("iPhone")通过此方法可以获取iPhone在字符串中的索引值(开头位置)
 //没有找到返回-1
 html.className="";
 if((userAgent.indexOf("iPhone"))!=-1){
 html.classList.add("iphone");
 }else if((userAgent.indexOf("Android"))!=-1)
 {
 html.classList.add("android");
 }else if((userAgent.indexOf("iPad"))!=-1){
 html.classList.add("ipad");
 }else{
 html.classList.add("pc");
 }
 if(window.innerWidth<640){
 html.classList.add('lt640');
 html.classList.add('lt960');
 html.classList.add('lt1200');
 }else if(window.innerWidth<960){
 html.classList.add('lt960');
 html.classList.add('lt1200');
 html.classList.add('gt640');
 }else if(window.innerWidth<1200){
 html.classList.add('lt1200');
 html.classList.add('gt640');
 html.classList.add('gt960');
 }else{
 html.classList.add('gt640');
 html.classList.add('gt960');
 html.classList.add('gt1200');
 
 }
 
  var screenWidth = window.innerWidth;
 var danwei = screenWidth/3.75;//屏幕的宽度/设计稿占满全屏的宽度为多少rem
 var html = document.querySelector("html")
 html.style.fontSize = danwei + 'px';
 }
 xys();
 window.onresize=function(){
 xys();
 }

})()

swiperEvent.js

var ylEvent = {
 eventAll:{
 //"自定义的事件名称":['事件要触发执行的函数1','事件要触发执行的函数2','事件要触发执行的函数3']
 
 },
 init:function(dom){
 dom.eventAll = {},
 dom.addEvent = this.addEvent;
 dom.emit = this.emit;
 dom.removeEvent = this.removeEvent
 dom.touchData = {};
 
 
 //body.emit('swiperLeft',"msg")
 
 dom.addEventListener("touchstart",function(e){
 //console.log(e)
 this.touchData.startX = e.touches[0].pageX;
 this.touchData.startY = e.touches[0].pageY
 })
 dom.addEventListener('touchmove',function(e){
 this.touchData.endX = e.touches[0].pageX;
 this.touchData.endY = e.touches[0].pageY;
 })
 dom.addEventListener("touchend",function(e){
 //console.log(e)
 var x = this.touchData.endX - this.touchData.startX;
 var y = this.touchData.endY - this.touchData.startY
 if( (Math.abs(x) > Math.abs(y)) && Math.abs(x)>100){
 if(x>0){
 //console.log('向右滑动')
 e.swiperDir = 'swiperRight'
 body.emit('swiperRight',e)
 }else{
 //console.log('向左滑动')
 e.swiperDir = 'swiperLeft'
 body.emit('swiperLeft',e)
 }
 }else if((Math.abs(x) < Math.abs(y)) && Math.abs(y)>100){
 if(y>0){
 //console.log('向下滑动')
 e.swiperDir = 'swiperBottom'
 body.emit('swiperBottom',e)
 }else{
 //console.log('向上滑动')
 e.swiperDir = 'swiperTop'
 body.emit('swiperTop',e)
 }
 }
 })
 },
 addEvent:function(eventName,callBackFn){
 
 if(this.eventAll[eventName]==undefined){
 this.eventAll[eventName] = []
 }
 this.eventAll[eventName].push(callBackFn)
 },
 emit:function(eventName,eventMsg){
 if(this.eventAll[eventName]!=undefined){
 this.eventAll[eventName].forEach(function(item,i){
 item(eventMsg)
 })
 }
 
 },
 removeEvent:function(eventName,callBackFn){
 var that = this
 this.eventAll[eventName].forEach(function(item,i){
 if(item==callBackFn){
 that.eventAll[eventName].splice(i,1)
 }
 })
 },
 
 }

index.html

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8" />
 <title></title>
 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
 <script src="js/js辅助式响应.js" type="text/javascript" charset="utf-8"></script>
 <link rel="stylesheet" type="text/css" href="css/style.css" />
 </head>
 <body>
 <!-- 
 1、贪吃蛇页面结构和样式
 2、能够绘制蛇
 3、能够绘制食物
 4、让蛇运动起来
 5、蛇能够吃食物
 6、蛇碰到自己就会失败
 -->
 
 <div class="page startGame">
 <div class="startBtn">开始游戏</div>
 </div>
 <div class="page gaming">
 <div class="score">
 <div class="left">
 score:<span class="num">0</span>
 </div>
 <div class="pauseBtn">
 暂停
 </div>
 </div>
 
 <div class="mainGame">
 
 </div>
 
 </div>
 <div class="page endGame">
 <h1>您最终获取分数是<span class="num">0</span>分</h1>
 <div class="reStartBtn">重新开始</div>
 </div>
 <script src="js/swiperEvent.js" type="text/javascript" charset="utf-8"></script>
 <script src="js/index.js" type="text/javascript" charset="utf-8"></script>
 </body>
</html>

结果:

javascript开发实现贪吃蛇游戏

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

Javascript 相关文章推荐
js 动态添加标签(新增一行,其实很简单,就是几个函数的应用)
Mar 26 Javascript
Google AJAX 搜索 API实现代码
Nov 17 Javascript
stream.js 一个很小、完全独立的Javascript类库
Oct 28 Javascript
javascript禁制后退键(Backspace)实例代码
Nov 15 Javascript
jQuery插件Zclip实现完美兼容个浏览器点击复制内容到剪贴板
Apr 30 Javascript
Angularjs中UI Router的使用方法
May 14 Javascript
jQuery基于toggle实现click触发DIV的显示与隐藏问题分析
Jun 12 Javascript
thinkjs之页面跳转同步异步操作
Feb 05 Javascript
xmlplus组件设计系列之图标(ICON)(1)
May 05 Javascript
微信小程序系列之自定义顶部导航功能
May 21 Javascript
vue-router二级导航切换路由及高亮显示的实现方法
Jul 10 Javascript
基于redis的小程序登录实现方法流程分析
May 25 Javascript
vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题
Jul 31 #Javascript
vscode中Vue别名路径提示的实现
Jul 31 #Javascript
Vue记住滚动条和实现下拉加载的完美方法
Jul 31 #Javascript
vue中渲染对象中属性时显示未定义的解决
Jul 31 #Javascript
JS可断点续传文件上传实现代码解析
Jul 30 #Javascript
Vue单文件组件开发实现过程详解
Jul 30 #Javascript
vue实现从外部修改组件内部的变量的值
Jul 30 #Javascript
You might like
PHP采集利器 Snoopy 试用心得
2011/07/03 PHP
ThinkPHP页面跳转success与error方法概述
2014/06/25 PHP
PHP遍历数组的三种方法及效率对比分析
2015/02/12 PHP
php+ajax登录跳转登录实现思路
2016/07/31 PHP
Node.js:Windows7下搭建的Node.js服务(来玩玩服务器端的javascript吧,这可不是前端js插件)
2011/06/27 Javascript
那些年,我还在学习jquery 学习笔记
2012/03/05 Javascript
打印json对象的内容及JSON.stringify函数应用
2013/03/29 Javascript
javascript获取下拉列表框当中的文本值示例代码
2013/07/31 Javascript
javascript中call和apply方法浅谈
2013/09/27 Javascript
javascript随机将第一个dom中的图片添加到第二个div中示例
2013/10/08 Javascript
javascript消除window.close()的提示窗口
2015/05/20 Javascript
Jsonp post 跨域方案
2015/07/06 Javascript
JS实现不规则TAB选项卡效果代码
2015/09/16 Javascript
探索Vue.js component内容实现
2016/11/03 Javascript
Bootstrap模态框案例解析
2017/03/05 Javascript
JS实现两周内自动登录功能
2017/03/23 Javascript
bootstrap插件treeview实现全选父节点下所有子节点和反选功能
2017/07/21 Javascript
详解如何使用webpack+es6开发angular1.x
2017/08/16 Javascript
Vim快速合并行及vim 将文件所有行合并到一行
2017/11/27 Javascript
微信小程序--特定区域滚动到顶部时固定的方法
2019/04/28 Javascript
JS如何判断对象是否包含某个属性
2020/08/29 Javascript
[04:44]DOTA2 2017全国高校联赛视频回顾
2017/08/21 DOTA
python查看数据类型的方法
2019/10/12 Python
flask实现验证码并验证功能
2019/12/05 Python
Python文本处理简单易懂方法解析
2019/12/19 Python
详解HTML5 Canvas绘制不规则图形时的非零环绕原则
2016/03/21 HTML / CSS
Ray-Ban雷朋美国官网:全球领先的太阳眼镜品牌
2016/07/20 全球购物
英国时尚服饰电商:Boohoo
2017/10/12 全球购物
罗技英国官方网站:Logitech UK
2020/11/03 全球购物
毕业生多媒体设计求职信
2013/10/12 职场文书
煤矿安全演讲稿
2014/05/09 职场文书
省级青年文明号申报材料
2014/05/23 职场文书
节能环保演讲稿
2014/08/28 职场文书
三好学生先进事迹材料
2014/08/28 职场文书
教师党的群众路线教育实践活动个人整改方案
2014/10/31 职场文书
php双向队列实例讲解
2021/11/17 PHP