扫雷要求
- 游戏的区域:
9*9的区域 - 方格可以打开与标记
左键打开,显示数字,为周围格子的地雷数,右键标记 - 地雷
地雷随机分布 - 踩到地雷时,游戏结束
所有的地雷显示出来 - 连锁开大空方格
- 剩余地雷数与计时器
- 游戏胜利条件
所有的方格除了地雷都被打开了,则游戏胜利
- 一个方格所包含的信息:
坐标 x y
是否是一个地雷
周围的地雷数 = 9
二维数组中存储的是周围的地雷数
html格式代码
<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="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>
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);
}
js代码块
//打开空格数量
var clearMineNum = 0;
//列
var col = 9
//行
var row = 9
//地雷数
var num = 10
//表示游戏是否结束 false表示未结束 true表示结束
var gg = false
/**
*
* r 行数
* c 列数
* num 地雷数
*/
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]++
}
}
}
//随机写入地雷的位置, 9表示地雷
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
}
function writeHtml(map) {
//先通过x轴数量写入ul,再讲过y轴的属性写入li
var gameBox = document.querySelector(".gameBox");
var gridHTML = "";
for (var i = 0; i < map.length; i++) {
gridHTML += '<ul class = "row" 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() {
var rows = document.querySelectorAll(".row")
for (var i = 0; i < rows.length; i++) {
//ele = ul
var element = rows[i];
element.onclick = function(event) {
// el 表示当前点击的元素
var el = event.target;
if (el.nodeName != "LI") {
return;
}
//TODO 判断是否被翻开了以及被标记了
if (el.style.background == "white" || !el.children[1].classList.contains("hide")) {
return;
}
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);
}
el.style.background = "white";
el.children[0].style.display = "inline"
clearMineNum++
//todo 是否胜利
judgeVictory()
} else if (mineNum == "9") {
// 踩到地雷,游戏结束
clearInterval(stopTime);
el.classList.add("boom");
alert("这数都不会算?去玩连连看吧")
gg = true;
//所有的地雷都显示
var all = document.querySelectorAll(".col");
//放置所有的地雷
var ff = [];
var allnum = 0;
//遍历所有的方格
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;
}
//如果点击不是li,则直接返回
console.log(el.nodeName);
if (el.nodeName != "LI") {
return;
}
var classList = el.children[1].classList;
var residue = document.querySelector(".residue");
var mineNum = parseInt(residue.innerHTML);
//如果没有旗子3,同时也没有被点开,则可以插旗子
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 === "") {
console.log(1);
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 = 99
init(row, col, num)
break;
default:
row = 9;
col = 9
num = 10
init(row, col, num)
break;
}
}
init(row, col, num)
图片是地雷和小旗可以直接放到文件夹中:
图片样式可以直接粘贴。
地雷图片的代码格式:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FF6600;}
.st1{fill:#3366CC;}
</style>
<path class="st0" d="M80.2,42l-9.8,15.8l21.4,1.6l15.9,6.6V48.5"/>
<path class="st0" d="M109.2,66.6c23.7,14.1,36.5,42.6,29.5,70.8c-8.6,34.5-43.4,55.5-77.9,46.9c-34.5-8.6-55.5-43.4-46.9-77.9
C20.5,79.6,43,61,68.8,58c7.4-0.9,15.2-0.4,22.9,1.5C97.9,61,103.7,63.4,109.2,66.6z"/>
<path class="st1" d="M76.3,190.6c-5.6,0-11.2-0.7-16.6-2C23,179.4,0.5,142.1,9.6,105.3C13,91.5,20.5,79.3,31.3,70
c10.5-9.1,23.3-14.7,37.1-16.3c8.1-0.9,16.4-0.4,24.4,1.6c6.6,1.6,12.8,4.2,18.6,7.7c12.4,7.4,22.4,18.8,28,32.1
c5.9,13.8,7.1,28.8,3.4,43.4C135.3,169.1,107.9,190.6,76.3,190.6L76.3,190.6z M76.2,61.9c-2.3,0-4.6,0.1-6.9,0.4
c-24.7,2.9-45.3,21-51.3,45.1c-8,32.1,11.7,64.7,43.7,72.6c4.7,1.2,9.6,1.8,14.5,1.8c27.6,0,51.5-18.7,58.1-45.5
c6.3-25.4-5-52.6-27.5-65.9c-5.1-3-10.5-5.3-16.3-6.7C86,62.5,81.1,61.9,76.2,61.9L76.2,61.9z M178,72.9c-17.7,0-32.1-14.4-32.2-32
c0-2.4,1.9-4.4,4.4-4.4c0,0,0,0,0,0h0c2.4,0,4.4,1.9,4.4,4.4c0,12.9,10.5,23.3,23.4,23.3h0.1c2.4,0,4.4,2,4.4,4.4
c0,2.4-2,4.4-4.4,4.4L178,72.9L178,72.9z"/>
<path class="st1" d="M94.3,46.5c-2.4,0-4.4-2-4.4-4.4V42c0-17.7,14.4-32.1,32-32.2h0.1c17.7,0,32.1,14.4,32.2,32
c0,2.4-1.9,4.4-4.4,4.4c0,0,0,0,0,0h0c-2.4,0-4.4-1.9-4.4-4.4c0-12.9-10.6-23.4-23.5-23.3c-12.9,0-23.3,10.5-23.3,23.4v0.1
C98.7,44.5,96.8,46.5,94.3,46.5z M175.4,112.3c-2.4,0-4.4-2-4.4-4.4c0-1.3,0.6-2.5,1.5-3.3c1.2-1,2.4-2.2,3.3-3.5
c6.8-8.7,6.5-21.1-0.6-29.5c-1.6-1.8-1.3-4.6,0.5-6.2c1.8-1.6,4.6-1.3,6.2,0.5l0,0c9.8,11.6,10.1,28.6,0.8,40.5
c-1.4,1.8-2.9,3.4-4.6,4.8C177.4,111.9,176.4,112.3,175.4,112.3z"/>
<path class="st1" d="M109.2,70.9c-2.2,0-4.1-1.7-4.3-3.9l-1.6-15.2l-22.5-5.6l-8.5,12.7c-1.3,2-4.1,2.5-6.1,1.2
c-2-1.3-2.5-4.1-1.2-6.1l10.2-15.3c1-1.5,2.9-2.3,4.7-1.8l28.4,7.1c1.8,0.4,3.1,2,3.3,3.8l1.9,18.3c0.2,2.4-1.5,4.5-3.9,4.8
C109.5,70.9,109.4,70.9,109.2,70.9L109.2,70.9z M35.6,100.7c-2.4,0-4.4-2-4.4-4.4c0-0.8,0.2-1.6,0.6-2.2c1.6-2.6,3.3-5,5.3-7.3
c1.6-1.8,4.4-2,6.2-0.4c1.8,1.6,2,4.4,0.4,6.2c-1.6,1.9-3.1,3.9-4.4,6C38.5,99.8,37.1,100.7,35.6,100.7z M63.6,168.1
c-0.4,0-0.7,0-1.1-0.1c-12.9-3.2-23.8-11.2-30.7-22.6c-6.9-11.4-8.9-24.8-5.7-37.7c0.6-2.3,2.9-3.8,5.3-3.2l0,0
c2.3,0.6,3.8,3,3.2,5.3c0,0,0,0,0,0c-2.6,10.6-1,21.7,4.7,31.1c5.7,9.4,14.6,16,25.3,18.7c2.3,0.6,3.8,2.9,3.2,5.3
C67.4,166.7,65.7,168.1,63.6,168.1L63.6,168.1z M190.6,116.7c1.6,0.8,2.4,2.6,2.1,4.3c-0.3,1.7-1.8,3.1-3.5,3.2l-3.7,0.4l1.7,3.3
c0.8,1.6,0.4,3.5-0.8,4.7c-1.3,1.2-3.2,1.4-4.8,0.5l-3.2-1.9l-0.6,3.7c-0.3,1.9-2,3.4-3.9,3.4c-1.6,0-3-0.9-3.7-2.4l-1.5-3.4
l-2.7,2.6c-1.3,1.3-3.2,1.5-4.8,0.7c-1.6-0.9-2.4-2.6-2-4.4l0.8-3.7l-3.7,0.6c-1.8,0.3-3.5-0.7-4.2-2.3c-0.8-1.6-0.4-3.5,1-4.7
l2.8-2.5l-3.3-1.7c-1.6-0.8-2.4-2.6-2.1-4.3c0.3-1.7,1.8-3.1,3.6-3.2l3.7-0.4L156,106c-0.8-1.6-0.5-3.5,0.8-4.7
c1.3-1.2,3.2-1.4,4.8-0.5l3.2,1.9l0.6-3.7c0.4-2.2,2.4-3.7,4.6-3.3c1.3,0.2,2.5,1.1,3,2.3l1.5,3.4l2.7-2.6c1.3-1.2,3.2-1.5,4.7-0.7
c1.6,0.8,2.4,2.6,2,4.4l-0.8,3.7l3.7-0.6c1.8-0.3,3.5,0.7,4.2,2.3c0.8,1.6,0.4,3.5-1,4.7l-2.8,2.5L190.6,116.7L190.6,116.7z
M176.9,118c-0.3-0.5-0.5-1-0.6-1.6c-0.1-0.6,0-1.2,0.2-1.7c-0.5-0.2-1-0.5-1.4-1c-0.4-0.4-0.7-0.9-0.9-1.5c-0.5,0.1-1.1,0.2-1.7,0
c-0.6-0.1-1.1-0.3-1.6-0.7c-0.4,0.4-0.8,0.8-1.4,1c-0.5,0.3-1.1,0.4-1.7,0.4c0,0.6-0.2,1.1-0.5,1.6c-0.3,0.5-0.7,1-1.1,1.3
c0.3,0.5,0.5,1,0.6,1.6c0.1,0.6,0,1.2-0.2,1.7c0.5,0.2,1,0.5,1.4,1c0.4,0.4,0.7,0.9,0.9,1.5c0.3-0.1,0.6-0.1,0.9-0.1
c0.3,0,0.5,0,0.8,0.1c0.6,0.1,1.1,0.3,1.6,0.7c0.4-0.4,0.8-0.8,1.4-1c0.5-0.3,1.1-0.4,1.7-0.4C175.4,119.7,176,118.7,176.9,118
L176.9,118z"/>
<path class="st0" d="M176.3,116.4c0.1,0.6,0.3,1.1,0.6,1.6c-0.9,0.7-1.5,1.8-1.6,2.9c-0.6,0-1.1,0.1-1.7,0.4c-0.5,0.3-1,0.6-1.4,1
c-0.5-0.3-1-0.6-1.6-0.7c-0.3,0-0.5-0.1-0.8-0.1c-0.3,0-0.6,0-0.9,0.1c-0.2-0.5-0.5-1-0.9-1.5c-0.4-0.4-0.9-0.8-1.4-1
c0.2-0.5,0.2-1.1,0.2-1.7c-0.1-0.6-0.3-1.1-0.6-1.6c0.5-0.3,0.8-0.8,1.1-1.3c0.3-0.5,0.4-1.1,0.5-1.6c0.6,0,1.1-0.1,1.7-0.4
c0.5-0.3,1-0.6,1.4-1c0.5,0.3,1,0.6,1.6,0.7c0.6,0.1,1.2,0.1,1.7,0c0.2,0.5,0.5,1,0.9,1.5c0.4,0.4,0.9,0.8,1.4,1
C176.3,115.2,176.2,115.8,176.3,116.4L176.3,116.4z"/>
</svg>
旗子的代码格式:
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1521894384315" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="643" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<defs>
<style type="text/css">
</style>
</defs>
<path d="M299.1 79.8v863.7" fill="#73D8A5" p-id="644">
</path>
<path d="M299.1 959.5c-8.8 0-16-7.2-16-16V79.9c0-8.8 7.2-16 16-16s16 7.2 16 16v863.6c0 8.8-7.2 16-16 16z" fill="#4C4848" p-id="645"></path>
<path d="M726 326.3L299.1 572.8v-493z" fill="#EE655F" p-id="646"></path>
<path d="M299.1 588.8c-2.8 0-5.5-0.7-8-2.1-5-2.9-8-8.1-8-13.9v-493c0-5.7 3-11 8-13.9 4.9-2.8 11.1-2.8 16 0L734 312.5c5 2.9 8 8.1 8 13.9s-3 11-8 13.9L307.1 586.7c-2.5 1.4-5.3 2.1-8 2.1z m16-481.2v437.6l379-218.8-379-218.8z" fill="#4C4848" p-id="647">
</path>
</svg>