如何用JS写个完整的扫雷游戏,过程是什么
Admin 2022-10-31 群英技术资讯 483 次浏览
扫雷大家都玩过,今天我们就是用JavaScript来打造扫雷游戏。废话不多说,直接看下效果;
上图是失败后的结果。
我们新建一个首页,在首页放置一个点击开始游戏的按钮,动态生成100个小格,即100div;然后通过点击div进行扫雷操作,然后扫雷成功或者失败显示对应的结果;
<body> <div class="wrapper"> <div class="btn" id="btn"></div> <!-- 开始游戏按钮--> <div class="box" id="box"></div> <!-- 存放小雷的div--> <div class="flagBox" id="flagBox"> <!-- 游戏结束才显示的当前雷数的div--> 当前剩余雷数: <span id="score">10</span> </div> <div class="alertBox" id="alertBox"> <!-- Game over弹出的框(窗口)--> <div class="alertImg" id="alertImg"> <div class="close" id="close"></div> </div> </div> </div> </body>
清楚默认边距
*{ margin:0; padding:0; }
页面最大div
.wrapper { width:100%; height:1000px; position: fixed; top:0; left:0; background-image: url('img/bg.jpg'); background-size: 100% 100%; }
效果如下:
开始游戏按钮
.btn{ height:140px; width:170px; position:absolute; left:50px; background-image: url('img/startGame.png'); background-size: 100% 100%; cursor: pointer; }
储存雷的大div
.box{ height:500px; width:500px; transform: perspective(800px) rotateX(45deg); margin:20px auto; border-top:1px solid #B25F27; border-left:1px solid #B25F27; box-shadow: 5px 5px 5px rgba(0,0,0,0.3); display:none; /* 先设置为none,开始游戏后显示block */ }
每一个方块的小div(一共100个)
.block{ width:49px; height:49px; border-right:1px solid #B25F27; border-bottom:1px solid #B25F27; box-shadow: 0 0 4px #333 inset; background-image: url('img/cao.jpg'); float: left; }
当前所剩雷数
.flagBox{ position:absolute; top:50px; left:50%; width:200px; height:50px; margin-left:-100px; color:#333; font-size:20px; font-weight: bolder; display:none; /* 先设置为none,开始游戏后显示block */ }
Game Over
.alertBox{ display:none; /* 先设置为none,开始结束显示block */ position:absolute; width:100%; height:100%; left:0; top:0; background-color: rgba(0,0,0,0.2); }
游戏结束弹出窗口右上角的X
.close{ position:absolute; right:0; top:0; height:40px; width:40px; background-image: url('img/closeBtn.png'); background-size: 100% 100%; cursor: pointer; }
var startBtn = document.getElementById('btn'); var box = document.getElementById('box'); var flagBox = document.getElementById('flagBox'); var alertBox = document.getElementById('alertBox'); var alertImg = document.getElementById('alertImg'); var closeBtn = document.getElementById('close'); var score = document.getElementById('score'); // 先声明变量,但是不初始化 var minesNum; var mineOver; var block; var mineMap = []; var startGameBool = true;
function init() { minesNum = 10; mineOver = 10; score.innerHTML = mineOver; for (var i = 0; i < 10; i++) { // 双层循环 10 * 10 个div for (var j = 0; j < 10; j++) { var con = document.createElement('div'); con.classList.add('block'); // 给创建出来的div添加类名 block con.setAttribute('id', i + '-' + j); box.appendChild(con); mineMap.push({ mine: 0 }); } } block = document.getElementsByClassName('block'); while (minesNum) { // 创建一个10次的循环,即设置10个雷 var mineIndex = Math.floor(Math.random() * 100); if (mineMap[mineIndex].mine === 0) { mineMap[mineIndex].mine = 1; block[mineIndex].classList.add('isLei'); // 10个雷有小div的block类属性,还有自己的属性,isLei minesNum--; } } }
function bindEvent() { startBtn.onclick = function () { // 开始按钮点击事件 if(startGameBool){ box.style.display = 'block'; flagBox.style.display = 'block'; init(); startGameBool = false; } } box.oncontextmenu = function () { return false; } box.onmousedown = function (e) { // 小div鼠标按下事件封装 var event = e.target; if (e.which == 1) { //Netscape/Firefox/Opera中不支持 window.event.keyCode,需要用event.which代替 leftClick(event); } else if (e.which == 3) { rightClick(event); } } closeBtn.onclick = function () { // 游戏结束,弹出game over窗口的关闭按钮事件封装 alertBox.style.display = 'none'; flagBox.style.display = 'none'; box.style.display = 'none'; box.innerHTML = ''; startGameBool = true; } }
leftClick 没有雷 --> 显示数字(代表以当前小格为中心周围8个格的雷数)扩散(当前周围八个格没有雷) 有雷 --> game Over
function leftClick(dom) { if(dom.classList.contains('flag')){ return; } var isLei = document.getElementsByClassName('isLei'); // 获得前面的10个雷的div if (dom && dom.classList.contains('isLei')) { // 判断是不是雷块 for (var i = 0; i < isLei.length; i++) { isLei[i].classList.add('show'); // 显示地雷背景图 } setTimeout(function () { alertBox.style.display = 'block'; alertImg.style.backgroundImage = 'url("img/over.jpg")'; // 上面显示雷,标志游戏结束 }, 800) } else { // 否则继续扫雷 var n = 0; var posArr = dom && dom.getAttribute('id').split('-'); var posX = posArr && +posArr[0]; var posY = posArr && +posArr[1]; dom && dom.classList.add('num'); for (var i = posX - 1; i <= posX + 1; i++) { for (var j = posY - 1; j <= posY + 1; j++) { var aroundBox = document.getElementById(i + '-' + j); if (aroundBox && aroundBox.classList.contains('isLei')) { n++; } } } dom && (dom.innerHTML = n); if (n == 0) { for (var i = posX - 1; i <= posX + 1; i++) { for (var j = posY - 1; j <= posY + 1; j++) { var nearBox = document.getElementById(i + '-' + j); if (nearBox && nearBox.length != 0) { if (!nearBox.classList.contains('check')) { nearBox.classList.add('check'); leftClick(nearBox); } } } } } } }
rightClick 没有标记并且没有数字 --> 进行标记;
有标记 --> 取消标记 --> 标记是否正确,10个都正确标记,提示成功;
如果已经出现,则点击无效果;
function rightClick(dom){ if(dom.classList.contains('num')){ // 如果已经出现,则点击无效果 return; } dom.classList.toggle('flag'); // 在元素中切换类名,切换为flag类名,显示红旗背景图;此处的雷被扫除了 if(dom.classList.contains('isLei') && dom.classList.contains('flag')){ mineOver --; // 雷数减一 } if(dom.classList.contains('isLei') && !dom.classList.contains('flag')){ mineOver ++; } score.innerHTML = mineOver; if(mineOver == 0){ // 扫完雷,标志雷数量为0 alertBox.style.display = 'block'; alertImg.style.backgroundImage = 'url("img/success.png")'; // 游戏胜利 } }
bindEvent()
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
本文主要介绍了Vue实现Echarts图表宽高自适应的实践,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
这篇文章主要介绍了React+umi+typeScript创建项目的过程,结合代码介绍了项目框架搭建的方式,本文给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
这篇文章给大家分享的是有关vue 动态创建组件的内容,下文给大家介绍了vue 动态创建组件并挂载到body的两种方式,有具体代码供大家参考,需要的朋友可以了解一下。
这篇文章主要为大家详细介绍了微信小程序自定义复选框,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
最近做了一个手机端系统,其中遇到了父页面需要携带参数跳转至子页面的问题,现已解决,下面分享一下实现过程,感兴趣的朋友一起看看吧
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008