用js来做扫雷效果
来喽来喽,带着代码奔过来喽
js部分
// 标记的旗子数量
var flagNum = 10;
// 点击按钮可以生成不同的难度。 初级:9*9 中级16*16 高级:16*30
var gameBox = document.querySelector(".gameBox");
function createHTML(row,col,num) {
var map = new Array();
for (var i = 0; i < row; i++) {
var item = new Array();
for (var j = 0; j < col; j++) {
item[j] = 0;
}
map[i] = item;
}
for (var k = 0; k < num; k++) {
// 地雷的行
var x = parseInt(Math.random() * row);
// 地雷的列
var y = parseInt(Math.random() * col);
if (map[x][y] == 9) {
k--;
continue;
}
// 假设数字9表示地雷
map[x][y] = 9;
// 让上面三个格子,下面三个格子,左右两个格子的数字+1
// x y 为坐标,array为数组
var plus = function(array,x,y){
if (x>=0&&y>=0&&x<row&&y<col) {
if (array[x][y]!=9) {
array[x][y]++;
}
}
}
// 上面三个格子的数量+1
for(var h = -1;h < 2;h++){
plus(map,x-1,y+h);
}
// 下面三个格子的数量+1
for(var m = -1;m < 2;m++){
plus(map,x+1,y+m)
}
// 左右两边的数量+1
plus(map,x,y-1);
plus(map,x,y+1)
}
var str = "";
for (var i = 0; i < map.length; i++) {
str += "<ul data-row="+i+">"
for (var j = 0; j < map[i].length; j++) {
if (map[i][j] == 0) {
map[i][j] = "";
}
str += "<li data-col="+j+">" +
"<span class='hide num-" + map[i][j] + "'>" + map[i][j] + "</span>" +
"<img src='img/flag.svg' class='img-flag hide'>"+
"</li>";
}
str += "</ul>";
}
gameBox.innerHTML = str;
}
var level = document.getElementsByClassName("level")[0];
// 记录难度的等级: 0 初级 1中级 2高级
var levelNum = 0;
level.onclick = function (ev) {
var target = ev.target;
switch (target.innerHTML) {
case "初级":
createHTML(9, 9,10);
levelNum = 0;
break;
case "中级":
createHTML(16, 16,20)
levelNum = 1;
break;
case "高级":
createHTML(16, 30,30);
levelNum = 2;
break;
case "重新开始":
switch (levelNum) {
case 0:
createHTML(9, 9,10);
break;
case 1:
createHTML(16, 16,20);
break;
case 2:
createHTML(16, 30,30);
break;
}
break;
}
}
// 初始化方法
function init() {
// 第一个9表示二维数组中有9个元素,每个元素都是一个数组,每个数组又包含9个元素。
createHTML(9,9,10);
}
// 小格子的点击事件
function show(){
// 左键点击事件
gameBox.onclick = function(ev){
var target = ev.target;
if(target.nodeName != "LI"){
return;
}
// 如果是已经翻开了,或者标记了,不应该做操作。
if (target.style.backgroundColor == "white" || !target.children[1].classList.contains("hide")) {
return;
}
// 判断点击的是不是地雷。 mine为9表示地雷。
var mine = target.firstChild.innerHTML;
if (mine != "9") {
// 雷数如果为空,说明这个格子周围没有一颗雷。应该自动打开。
if (mine == "") {
// 获取当前格子的横坐标
var x = parseInt(target.parentNode.dataset.row);
// 获取当前格子的纵坐标
var y = parseInt(target.dataset.col);
showNoMine(x,y);
}
target.style.backgroundColor = "white";
target.firstChild.classList.remove("hide");
}else{
// 游戏结束
alert("这都不会算?去玩连连看吧");
// 让所有的地雷显示出来。
var all = document.querySelectorAll(".num-9");
for (var i = 0; i < all.length; i++) {
all[i].classList.remove("hide");
all[i].classList.add("boom");
all[i].innerHTML = "";
}
}
}
gameBox.oncontextmenu = function(ev){
// 阻止浏览器的默认行为
ev.preventDefault();
var el = ev.target;
if (el.parentNode.nodeName == "LI") {
el = el.parentNode;
}
if (el.nodeName != "LI") {
return;
}
// 如果没有插旗子,也没有被点开,则可以标记
if (el.style.backgroundColor!="white"&&el.children[1].classList.contains("hide")&&flagNum>0) {
el.children[1].classList.remove("hide");
// 剩余雷数-1;
flagNum--;
}else if(!el.children[1].classList.contains("hide")){
// 剩余雷数+1;
flagNum++;
}
judgeVictory();
}
}
// 判断游戏是否胜利
function judgeVictory(){
// 所有的雷上面都插上了旗子,说明游戏胜利。
var mine = document.querySelectorAll(".num-9");
// 假设所有的雷都插上了旗子。
var flag = true;
for (var i = 0; i < mine.length; i++) {
if(mine[i].nextElementSibling.classList.contains("hide")){
flag = false;
break;
}
}
if (flag) {
alert("游戏胜利!")
}
}
// 当前格子的横纵坐标。
function showNoMine(x,y){
var ul = document.querySelectorAll("ul");
var open = function(x,y){
if (x>=0&&x<ul.length) {
// 执行打开操作。
var lis = ul[x].getElementsByTagName("li");
if (y>=0&&y<lis.length) {
var el = lis[y];
// 自动打开必须是未打开的方格。
if (el.style.backgroundColor != "white") {
el.style.backgroundColor = "white";
el.firstChild.classList.remove("hide");
// 如果打开的方格又是一个空白,则继续打开。
if (el.firstElementChild.innerHTML == "") {
showNoMine(x,y)
}
}
}
}
}
// 上面三个格子打开
for(var h = -1;h < 2;h++){
open(x-1,y+h);
}
// 下面三个格子的数量+1
for(var m = -1;m < 2;m++){
open(x+1,y+m)
}
// 左右两边的数量+1
open(x,y-1);
open(x,y+1)
}
init();
show();
html部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="css/mine.css">
</head>
<body>
<!--
1.先完成静态页面。
-->
<!-- 等级选择模块 -->
<div class="level">
<button class="btn">初级</button>
<button class="btn">中级</button>
<button class="btn">高级</button>
<button class="btn">重新开始</button>
</div>
<div class="gameBox">
</div>
<!-- 地雷游戏信息:雷数和时间 -->
<div class="info">
<p>剩余雷数:
<span class="residue">10</span>
</p>
<p>时间:
<span class="time">10</span>
</p>
</div>
<script src="js/mine6.0.js"></script>
</body>
</html>
css部分
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
text-align: center;
}
li{
width: 22px;
height: 22px;
display: inline-block;
line-height: 22px;
background-color: rgba(32, 226, 255, 0.4);
border: 1px solid rgb(129, 129, 129);
margin: 1px;
vertical-align: top;
position: relative;
}
.level{
margin: 30px;
text-align: center;
}
.info{
text-align: center;
margin-top: 20px;
}
.info p{
display: inline-block;
width: 130px;
margin: 0 auto;
}
.level button{
background-color: rgb(67, 183, 189);
padding: 5px 8px;
border: none;
border-radius: 3px;
color: #fff;
cursor: pointer;
}
.level button:hover{
background-color: rgb(23, 132, 138);
}
.img-flag{
width: 18px;
height: 18px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
.hide{
display: none;
}
.num-1{
color: #2ecc71;
}
.num-2{
color: #f1c40f;
}
.num-3{
color:#e74c3c;
}
.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;
}
.boom{
background-image: url("../img/boom.svg");
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
li span{
width: 100%;
height: 100%;
display: inline-block;
}