网络编程 
首页 > 网络编程 > 浏览文章

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

<!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="/UploadFiles/2021-04-02/js辅助式响应.js">

结果:

javascript开发实现贪吃蛇游戏

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

上一篇:基于vue--key值的特殊用处详解
下一篇:vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题
高通与谷歌联手!首款骁龙PC优化Chrome浏览器发布
高通和谷歌日前宣布,推出首次面向搭载骁龙的Windows PC的优化版Chrome浏览器。
在对骁龙X Elite参考设计的初步测试中,全新的Chrome浏览器在Speedometer 2.1基准测试中实现了显著的性能提升。
预计在2024年年中之前,搭载骁龙X Elite计算平台的PC将面世。该浏览器的提前问世,有助于骁龙PC问世就获得满血表现。
谷歌高级副总裁Hiroshi Lockheimer表示,此次与高通的合作将有助于确保Chrome用户在当前ARM兼容的PC上获得最佳的浏览体验。