javascript开发实现贪吃蛇游戏
(编辑:jimmy 日期: 2024/12/26 浏览:3 次 )
贪吃蛇的例子:
在此例子中,利用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
下一篇:vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题