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获取IP、MAC和主机名的五种方法
Nov 14 Javascript
jQuery中的编程范式详解
Dec 15 Javascript
node.js中的fs.mkdir方法使用说明
Dec 17 Javascript
jquery实现不包含当前项的选择器实例
Jun 25 Javascript
jquery中键盘事件小结
Feb 24 Javascript
基于JavaScript实现本地图片预览
Feb 08 Javascript
JS实现多张图片预览同步上传功能
Jun 23 Javascript
Vue.js项目部署到服务器的详细步骤
Jul 17 Javascript
用Vue.extend构建消息提示组件的方法实例
Aug 08 Javascript
在小程序Canvas中使用measureText的方法示例
Oct 19 Javascript
egg.js的基本使用和调用数据库的方法示例
May 18 Javascript
Nuxt的路由动画效果案例
Nov 06 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读取文件内容的几种方法详解
2013/06/26 PHP
使用图灵api创建微信聊天机器人
2015/07/23 PHP
PHP实现批量修改文件后缀名的方法
2015/07/30 PHP
yii2整合百度编辑器umeditor及umeditor图片上传问题的解决办法
2016/04/20 PHP
一个JQuery操作Table的代码分享
2012/03/30 Javascript
JavaScript中json对象和string对象之间相互转化
2012/12/26 Javascript
JS中Iframe之间传值及子页面与父页面应用
2013/03/11 Javascript
js模仿hover的具体实现代码
2013/12/30 Javascript
JavaScript的常见兼容问题及相关解决方法(chrome/IE/firefox)
2013/12/31 Javascript
Node.js编写组件的三种实现方式
2016/02/25 Javascript
详解Wondows下Node.js使用MongoDB的环境配置
2016/03/01 Javascript
Javascript中的数组常用方法解析
2016/06/17 Javascript
BootStrap 实现各种样式的进度条效果
2016/12/07 Javascript
JS实现二叉查找树的建立以及一些遍历方法实现
2017/04/17 Javascript
Node.js 使用命令行工具检查更新
2017/06/08 Javascript
基于javascript 显式转换与隐式转换(详解)
2017/12/15 Javascript
swiper 自动图片无限轮播实现代码
2018/05/21 Javascript
layui框架table 数据表格的方法级渲染详解
2018/08/19 Javascript
vue template中slot-scope/scope的使用方法
2018/09/06 Javascript
Webpack设置环境变量的一些误区详解
2019/12/19 Javascript
利用python发送和接收邮件
2016/09/27 Python
使用Python进行AES加密和解密的示例代码
2018/02/02 Python
Python实现类似比特币的加密货币区块链的创建与交易实例
2018/03/20 Python
Python中Numpy包的安装与使用方法简明教程
2018/07/03 Python
python进程和线程用法知识点总结
2019/05/28 Python
详细整理python 字符串(str)与列表(list)以及数组(array)之间的转换方法
2019/08/30 Python
Python semaphore evevt生产者消费者模型原理解析
2020/03/18 Python
使用jupyter notebook将文件保存为Markdown,HTML等文件格式
2020/04/14 Python
python中函数返回多个结果的实例方法
2020/12/16 Python
英国手工布艺沙发在线购买:Sofas & Stuff
2018/03/02 全球购物
中专生自我鉴定范文
2014/02/02 职场文书
自强自立美德少年事迹材料
2014/08/16 职场文书
村委会贫困证明范本
2014/09/17 职场文书
离婚协议书格式
2014/11/21 职场文书
2015年圣诞节活动总结
2015/03/24 职场文书
爱鸟护鸟的宣传语
2015/07/13 职场文书