原生js实现自定义难度的扫雷游戏
本文实例为大家分享了js实现扫雷游戏的具体代码,供大家参考,具体内容如下
游戏功能:
1、有四个难度2、可以自定难度
1、html相关代码
<!DOCTYPE html><html lang='en'> <head> <meta charset='UTF-8'> <meta name='viewport' content='width=device-width, initial-scale=1.0'> <title>扫雷</title> <script src='https://www.haobala.com/bcjs/js/mine.js'></script> <link rel='stylesheet' href='https://www.haobala.com/bcjs/css/mine.css' ></head><!-- 需求分析: 1.游戏的区域: 9*9的区域 2.方格可以打开与标记 左键打开,显示数字,为周围格子的地雷数,右键标记 3.地雷 地雷随机分布 4.踩到地雷时,游戏结束 所有的地雷显示出来 5.连锁开大空方格 6.剩余地雷数与计时器 7.游戏胜利条件 所有的方格除了地雷都被打开了,则游戏胜利 一个方格所包含的信息: 坐标 x y 是否是一个地雷 周围的地雷数 = 9 二维数组中存储的是周围的地雷数 --> <body> <div class='level'> <button type='button' name='button' class='choice-level'>自定义</button> <button type='button' name='button' class='choice-level'>初级</button> <button type='button' name='button' class='choice-level'>中级</button> <button type='button' name='button' class='choice-level'>高级</button> <button type='button' name='button' class='choice-level'>魔鬼级</button> <button type='button' name='button' class='restart'>重新开始</button> </div> <div class='gameBox'></div> <div class='info'> <p>剩余雷数: <span class='residue'></span> </p> <p> TIME: <span class='tick'></span>S </p> </div></body> </html>
2、css样式
*{ margin: 0; padding: 0;}.gameBox{ margin-top: 30px;}body{ font-size: 0;}ul{ list-style: none; text-align: center; overflow: hidden;}.col{ display: inline-block; width: 22px; height: 22px; line-height: 22px; background-color: rgba(32, 226, 255, 0.4); border: 1px solid rgb(129, 129, 129); font-size: 16px; margin: 1.5px; vertical-align: top; position: relative;}.col:hover{ background-color: #0af;}.col span{ cursor: default;}.hide{ display: none;}.boom{ background: url('../img/boom.svg') no-repeat 2.5px 2px; background-size: 18px 18px;}.num-1{ color: rgb(8, 153, 235);}.num-2{ color: rgb(255, 45, 178);}.num-3{ color:#16a085;}.num-4{ color: #8e44ad;}.num-5{ color: rgb(255, 167, 45);}.num-6{ color: rgb(8, 126, 176);}.num-7{ color: #e67e22;}.num-8{ color: #c0392b;}.img-flag{ width: 18px; height: 18px; position: absolute; top: 3px; left: 3px;}.level{ margin-top: 30px; font-size: 20px; text-align: center;}.level button{ padding: 5px 8px; background-color: rgb(67, 183, 189); border: none; outline: none; border-radius: 3px; cursor: pointer; color: #fff;}.level button:hover{ background-color: rgb(23, 132, 138);}.info{ margin-top: 30px; font-size: 16px; text-align: center;}.info p{ display: inline-block; width: 130px; margin: 0 auto;}.info p span{ color: rgb(67, 183, 189);}
3、js代码
window.onload = function() { var row = 4; var col = 4; var num = 1; // 判断踩雷之后不能胜利 var gg = false; // 生成地图 function mineMap(r, c, num) { // 定义行 var map = []; //给行数,生成二维数组 for (var i = 0; i < r; i++) { map[i] = new Array() } // 赋值 for (var i = 0; i < map.length; i++) { for (var j = 0; j < c; j++) { // //周围的地雷数 map[i][j] = 0; } } var plus = function(array, x, y) { if (x >= 0 && x < r && y >= 0 && y < c) { if (array[x][y] !== 9) { array[x][y]++ } } } for (var i = 0; i < num; i++) { var x = Math.floor(Math.random() * r) var y = Math.floor(Math.random() * c) if (map[x][y] != 9) { map[x][y] = 9 //上下6个 +1 for (var j = -1; j < 2; j++) { //上三个 plus(map, x - 1, y + j) //下三个 plus(map, x + 1, y + j) } //左右2个 +1 plus(map, x, y - 1) plus(map, x, y + 1) } else { //重新随机 num++ } } return map; } //先通过x轴数量写入ul,再讲过y轴的属性写入li function writeHtml(map) { // 获取盒子 var gameBox = document.querySelector('.gameBox'); // 声明空字符串,存放生成的ul、li var gridHTML = ''; for (var i = 0; i < map.length; i++) { gridHTML += ’<ul data-x='’ + i + ’'>’; //生成li for (var j = 0; j < map[0].length; j++) { var m = map[i][j] if (m == 0) { m = ''; } gridHTML += '<li class=’col’ data-y=' + j + '>' + '<span class=’hide num-' + m + '’>' + m + '</span>' + '<img src=’img/flag.svg’ class=’img-flag hide’>' + '</li>' } gridHTML += ’</ul>’ gameBox.innerHTML = gridHTML; } } //给方格绑定事件, 点开数字 地雷 右键标记 function show() { // 获取行ul var rows = document.querySelectorAll('.row'); // 遍历所有ul for (var i = 0; i < rows.length; i++) { var element = rows[i]; // 添加点击事件 element.onclick = function(event) { // 当前点击元素 var el = event.target; // 判断是否为li if (el.nodeName != 'LI') { return; } //todo 判断是否被打开以及标记了 if (el.style.background == 'white' || !el.children[1].classList.contains('hide')) { return; } // 获取span标签内容 var mineNum = el.children[0].innerHTML; if (mineNum !== '9' && el.style.background !== 'white') { // 空白连锁打开 if (mineNum == '') { var x = parseInt(el.parentNode.dataset.x); var y = parseInt(el.dataset.y); showNoMine(x, y); } // li背景变白色;span显示 el.style.background = 'white'; el.children[0].style.display = 'inline'; // 判断打开数量 clearMineNum++; // 胜利函数 judgeVictory() } else if (mineNum == '9') { // 清除胜利计时器 clearInterval(stopTime); // li添加类名 el.classList.add('boom'); alert('你真菜!') gg = true; // 显示所有地雷,获取所有li var all = document.querySelectorAll('.col'); // 放置所有的地雷 var ff = []; var allnum = 0; // 遍历所有li for (var i = 0; i < all.length; i++) { if (all[i].children[0].innerHTML == '9') {// 雷赋值给数组ff[allnum] = all[i];allnum++; } } // 设置一个计时器一个一个打开雷 allnum = 0; var stop = setInterval(function() { ff[allnum].classList.add('boom') allnum++; // 判断结束条件 if (allnum == ff.length) {// 清除计时器clearInterval(stop); } }, 30) } } // 右键标记地雷 element.oncontextmenu = function(event) { // 阻止右键菜单 event.preventDefault(); // 获取当前点击节点 var el = event.target; // 判断是否是 if (el.parentNode.nodeName == 'LI') { el = el.parentNode; } if (el.nodeName != 'LI') { return; } // 获取img var classList = el.children[1].classList; // 剩余雷数 var residue = document.querySelector('.residue'); var mineNum = parseInt(residue.innerHTML); // 如果没有旗子,没有被点开,可以插旗子 if (classList.contains('hide') && el.style.background != 'white') { // 移除隐藏 classList.remove('hide'); // 获取雷数 mineNum--; } else if (el.style.background != 'white') { classList.add('hide'); // 判断雷数 if (mineNum < num) { mineNum++; } } // 剩余雷数 residue.innerHTML = mineNum; } } } function judgeVictory() { //游戏胜利 if (clearMineNum === (row * col - num)) { //做一个小动画 var all = document.querySelectorAll('.col'); var allNum = 0; var stop = setInterval(function() { var r = Math.floor(Math.random() * 256) var g = Math.floor(Math.random() * 256) var b = Math.floor(Math.random() * 256) all[allNum].style.background = 'rgba(' + r + ',' + g + ',' + b + ',0.6)'; //将旗子和span都隐藏 all[allNum].children[0].style.display = 'none' all[allNum].children[1].style.display = 'none' allNum++ if (allNum === all.length) { clearInterval(stop) if (!gg) { alert('大吉大利,今晚吃鸡') init(row, col, num) } } }, 20) } } //自动打开空格 function showNoMine(x, y) { for (var i = -1; i <= 1; i++) { if (x + i >= 0 && x + i < row) { // 获取当前行 var rowElement = document.querySelectorAll('.row')[x + i]; for (var j = -1; j <= 1; j++) { if (y + j >= 0 && y + j < col) { //获取当前单元格 var el = rowElement.children[y + j] //自动打开必须是未打开的方格 if (el.style.background != 'white') { el.style.background = 'white' el.children[0].style.display = 'inline'//打开方格数量+1 clearMineNum++ //判断游戏是否胜利 judgeVictory(clearMineNum)if (el.children[0].innerText === '') {showNoMine(x + i, y + j) } } } } } // if (x + i >= 0 && x + i < row) { // // 获取当前行 // var rowElement = document.querySelectorAll('.row')[x + i]; // for (var j = -1; j <= 1; j++ && y + j < col) { // // 获取当前单元格 // var el = rowElement.children[y + j]; // if (el.style.background !== 'white') { // el.style.background = 'white'; // el.children[0].style.display = 'inline'; // // 打开放格数量加1 // clearMineNum++; // // 判断游戏是否胜利 // judgeVictory(clearMineNum); // // 判断打开周围的放格周围是否为空 // if (el.children[0].innerHTML === '') { // showNoMine(x + i, y + j) // } // } // } // } } } //初始化方法 var stopTime; function init(row, col, num) { //数据初始化 clearMineNum = 0 gg = false; //清除原来的地图,生成新的地图 var box = document.querySelector('.gameBox') box.innerHTML = ''; var map = mineMap(row, col, num); // 新建地图 writeHtml(map); show() //将雷数写入html中 var residue = document.querySelector('.residue') residue.innerHTML = num // 获取计时 var tick = document.querySelector('.tick'); var i = 0; // 初始化 tick.innerHTML = i; // 清除计时 clearInterval(stopTime); // 时间计时器 stopTime = setInterval(function() { tick.innerHTML = ++i }, 1000) } // 重置 var restart = document.querySelector('.restart'); restart.onclick = function(event) { //阻止冒泡 event.stopPropagation() init(row, col, num) } // 自定义 var level = document.querySelector('.level') level.onclick = function(event) { var el = event.target; switch (el.innerHTML) { case '初级': row = 9; col = 9; num = 10; init(row, col, num) break; case '中级': row = 16; col = 16; num = 40; init(row, col, num) break; case '高级': row = 16; col = 30; num = 479; init(row, col, num) break; case '魔鬼级': row = 40; col = 50; num = 300; init(row, col, num) break; case '自定义': row = prompt('请输入列数!'); col = prompt('请输入行数!'); num = prompt('请输入你想要的雷数,(请慎重选择)'); init(row, col, num); break; default: row = 9; col = 9; num = 10; init(row, col, num) break; } } init(row, col, num)}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持好吧啦网。
相关文章: