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 相关文章推荐
通用javascript脚本函数库 方便开发
Oct 13 Javascript
基于JQuery的一个简单的鼠标跟随提示效果
Sep 23 Javascript
一个简单的Ext.XTemplate的实例代码
Mar 18 Javascript
js 使用form表单select类实现级联菜单效果
Dec 19 Javascript
在js中实现邮箱格式的验证方法(推荐)
Oct 24 Javascript
JS实现的图片预览插件与用法示例【不上传图片】
Nov 25 Javascript
详解javascript中对数据格式化的思考
Jan 23 Javascript
微信小程序request出现400的问题解决办法
May 23 Javascript
vuejs+element-ui+laravel5.4上传文件的示例代码
Aug 12 Javascript
JS实现图片放大镜插件详解
Nov 06 Javascript
详解如何用模块化的方式写vuejs
Dec 16 Javascript
使用Canvas绘制一个游戏人物属性图
Mar 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中unset,array_splice删除数组中元素的区别
2014/07/28 PHP
Smarty最简单实现列表奇偶变色的方法
2015/07/01 PHP
php可变长参数处理函数详解
2017/02/22 PHP
php基于数组函数实现关联表的编辑操作示例
2017/07/04 PHP
thinkphp5框架实现的自定义扩展类操作示例
2019/05/16 PHP
jQuery EasyUI 中文API Button使用实例
2010/04/14 Javascript
Firefox中beforeunload事件的实现缺陷浅析
2012/05/03 Javascript
兼容ie、firefox的图片自动缩放的css跟js代码分享
2013/08/12 Javascript
js opener的使用详解
2014/01/11 Javascript
javascript的tab切换原理与效果实现方法
2015/01/10 Javascript
jQuery实现鼠标滑过Div层背景变颜色的方法
2015/02/17 Javascript
Juery解决tablesorter中文排序和字符范围的方法
2015/05/06 Javascript
js实现固定显示区域内自动缩放图片的方法
2015/07/18 Javascript
javascript瀑布流式图片懒加载实例
2020/06/28 Javascript
使用js获取地址栏参数的方法推荐(超级简单)
2016/06/14 Javascript
javascript中异常处理案例(推荐)
2016/10/03 Javascript
深入理解javascript中的 “this”
2017/01/17 Javascript
vue.js组件vue-waterfall-easy实现瀑布流效果
2017/08/22 Javascript
JavaScript+CSS相册特效实例代码
2017/09/07 Javascript
js事件on动态绑定数据,绑定多个事件的方法
2018/09/15 Javascript
微信小程序实现多选删除列表数据功能示例
2019/01/15 Javascript
浅谈python中的getattr函数 hasattr函数
2016/06/14 Python
python 处理微信对账单数据的实例代码
2019/07/19 Python
python获取网络图片方法及整理过程详解
2019/12/20 Python
如何用python爬取微博热搜数据并保存
2021/02/20 Python
css3 box-shadow阴影(外阴影与外发光)图示讲解
2017/08/11 HTML / CSS
HTML5 客户端数据库简易使用:IndexedDB
2019/12/19 HTML / CSS
苹果台湾官网:Apple台湾
2019/01/05 全球购物
新西兰购物网站:TheMarket NZ
2020/09/19 全球购物
招商专员岗位职责
2014/02/08 职场文书
教师党员学习群众路线心得体会
2014/11/04 职场文书
统计工作个人总结
2015/03/03 职场文书
企业内部管理控制:银行存款控制制度范本
2020/01/10 职场文书
详解MySQL 用户权限管理
2021/04/20 MySQL
解决SpringCloud Feign传对象参数调用失败的问题
2021/06/23 Java/Android
Redis模仿手机验证码发送的实现示例
2021/11/02 Redis