Files
tudoudilei/saolei/mineClearance.js
2025-10-21 10:38:28 +00:00

695 lines
25 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* author: payen S.Tsung 丛培森
* date2016.09
* bloghttp://blog.csdn.net/q1056843325
*/
(function (global) {
var srcPath = 'mine_img';
var srcArr = [
'0.jpg',
'1.jpg','2.jpg','3.jpg','4.jpg',
'5.jpg','6.jpg','7.jpg','8.jpg',
'1_w.jpg','2_w.jpg','3_w.jpg','4_w.jpg',
'5_w.jpg','6_w.jpg','7_w.jpg','8_w.jpg',
'1_wrong.gif','2_wrong.gif','3_wrong.gif','4_wrong.gif',
'5_wrong.gif','6_wrong.gif','7_wrong.gif','8_wrong.gif',
's.jpg','s_light.jpg','s_light0.jpg',
'bomb.jpg','bomb0.jpg','bomb_w.jpg',
'flag.jpg','flag_light.jpg','flag_light0.jpg',
'mark.jpg','mark_light.jpg','mark_light0.jpg',
];
var $mcStart = document.getElementById('mc_start'),
$mcLevel = document.getElementById('mc_level'),
$btnCollection = document.getElementsByTagName('button'),
$btnStart = $btnCollection[0],
$btnPri = $btnCollection[1],
$btnMid = $btnCollection[2],
$btnExp = $btnCollection[3],
$gameTime = document.getElementById('mc_game_time'),
$gameMine = document.getElementById('mc_game_mine'),
$priGame = document.getElementById('mc_pri_game'),
$midGame = document.getElementById('mc_mid_game'),
$expGame = document.getElementById('mc_exp_game'),
$win = document.getElementById('mc_gameover_win'),
$lose = document.getElementById('mc_gameover_lose'),
$overTime = document.getElementById('mc_gameover_time'),
$overChoose = document.getElementById('mc_gameover_choose'),
$replay = document.getElementById('mc_replay'),
$reselect = document.getElementById('mc_reselect'),
upExPos = {
'top': '-400px',
'opacity': '0'
},
downExPos = {
'bottom': '-400px',
'opacity': '0'
},
upPos = {
'top': '0',
'opacity': '1'
},
downPos = {
'bottom': '0',
'opacity': '1'
},
midPos = {
'top': '350px',
'opacity': '1'
},
priLevelPos = {
'bottom': '252px',
'opacity': '1'
},
highLevelPos = {
'bottom': '173px',
'opacity': '1'
},
iRowNum,
iLineNum,
iMineNum,
iGridNum,
timeStart,
timeEnd,
msgArr,
mineArr,
curGameLevel,
iDigNum,
bGameOver;
//资源预加载函数
var preloadingSrc = (function(){
var loadedNum = 0;
return function(srcPath, srcArr){
var imgs = [];
var toLoadNum = srcArr.length;
for(var i = 0; i < toLoadNum; i++){
imgs[i] = new Image();
imgs[i].src = srcPath + '/' + srcArr[i];
imgs[i].onload = function(){
loadedNum++;
if(toLoadNum === loadedNum){
console.log('全部图片资源加载完毕');
}
}
}
}
})();
preloadingSrc(srcPath, srcArr);
//方格信息构造函数
function MsgObj(x, y) {
this.x = x;
this.y = y;
this.isDigged = false;
this.isFlagged = false;
this.isMarked = false;
this.isMine = false;
this.figure = 0;
this.bCheck = false;
}
//初始化雷数组函数
function initMineArr(mineArray, iMineNum, iGridNum) {
while (true) {
if (mineArray.length === iMineNum) {
mineArray = mineArray.unique();
if (mineArray.length === iMineNum) {
break;
}
}
mineArray.push(Math.floor(Math.random() * iGridNum));
}
mineArr = mineArray;
//console.log(mineArr);
}
//初始化方格信息数组函数
function initMsgArr(msgArr, mineArr, iRowNum, iLineNum) {
//console.log(mineArr);
var x, y;
for (var i = 0; i < iRowNum; i++) {
msgArr[i] = [];
for (var j = 0; j < iLineNum; j++) {
msgArr[i][j] = new MsgObj(i, j);
}
}
for (var k = 0, mlen = mineArr.length; k < mlen; k++) {
x = parseInt(mineArr[k] / iLineNum);
y = mineArr[k] % iLineNum;
msgArr[x][y].isMine = true;
}
}
//初始化数字函数
function initFigure(msgArr, iRowNum, iLineNum) {
var iCount,
arr;
for (var i = 0; i < iRowNum; i++) {
for (var j = 0; j < iLineNum; j++) {
iCount = 0;
arr = roundArray(i, j, iRowNum, iLineNum);
if (!msgArr[i][j].isMine) {
for (var k = 0, len = arr.length; k < len; k++) {
if (msgArr[arr[k].x][arr[k].y].isMine) {
iCount++;
}
}
}
msgArr[i][j].figure = iCount;
}
}
}
//周围方格数组函数
function roundArray(x, y, iRowNum, iLineNum) {
function Coord(x, y) {
this.x = x;
this.y = y;
}
var roundArr = [];
roundArr.push(new Coord(x, y));
if (x - 1 >= 0) {
roundArr.push(new Coord(x - 1, y));
if (y - 1 >= 0) {
roundArr.push(new Coord(x - 1, y - 1));
}
}
if (x + 1 <= iRowNum - 1) {
roundArr.push(new Coord(x + 1, y));
if (y + 1 <= iLineNum - 1) {
roundArr.push(new Coord(x + 1, y + 1));
}
}
if (y - 1 >= 0) {
roundArr.push(new Coord(x, y - 1));
if (x + 1 <= iRowNum - 1) {
roundArr.push(new Coord(x + 1, y - 1));
}
}
if (y + 1 <= iLineNum - 1) {
roundArr.push(new Coord(x, y + 1));
if (x - 1 >= 0) {
roundArr.push(new Coord(x - 1, y + 1));
}
}
return roundArr;
}
//触发事件方格的坐标函数
function coordOfGrid(ele) {
var parNode = ele.parentNode;
return {
x: parNode.eleIndex(),
y: ele.eleIndex()
}
}
//插入数字背景图片函数
function addFigureImg(ele, num) {
switch (num) {
case 1:
ele.className = "number1";
break;
case 2:
ele.className = "number2";
break;
case 3:
ele.className = "number3";
break;
case 4:
ele.className = "number4";
break;
case 5:
ele.className = "number5";
break;
case 6:
ele.className = "number6";
break;
case 7:
ele.className = "number7";
break;
case 8:
ele.className = "number8";
break;
}
}
//插入数字错误背景动图函数
function addFalseFigureImg(ele, num) {
switch (num) {
case 1:
ele.className = "number1_wrong";
break;
case 2:
ele.className = "number2_wrong";
break;
case 3:
ele.className = "number3_wrong";
break;
case 4:
ele.className = "number4_wrong";
break;
case 5:
ele.className = "number5_wrong";
break;
case 6:
ele.className = "number6_wrong";
break;
case 7:
ele.className = "number7_wrong";
break;
case 8:
ele.className = "number8_wrong";
break;
}
}
//检查游戏胜利函数
function digJudge(gameLevel, msgArr, iRowNum, iLineNum) {
iDigNum++;
//console.log(iDigNum,iRowNum*iLineNum - iDigNum);
var curGridEle;
if (iDigNum === iGridNum - iMineNum) {
for (var i = 0; i < iRowNum; i++) {
for (var j = 0; j < iLineNum; j++) {
curGridEle = gameLevel.children[i].children[j];
if (!msgArr[i][j].isDigged && !msgArr[i][j].isFlagged) {
msgArr[i][j].isDigged = true;
if (msgArr[i][j].isMine) {
curGridEle.className = "flag";
msgArr[i][j].isFlagged = true;
} else if (msgArr[i][j].figure != 0) {
addFigureImg(curGridEle, msgArr[i][j].figure);
} else {
curGridEle.className = "white";
}
}
}
}
gameOver(true);
}
}
//挖开方块函数
function digGrid(gameLevel, msgArr, x, y) {
if (msgArr[x][y].isDigged || msgArr[x][y].isFlagged) {
return;
}
var index = msgArr[x][y].figure,
curGridEle = gameLevel.children[x].children[y];
if (index !== 0) {
addFigureImg(curGridEle, index);
} else {
curGridEle.className = "white";
}
msgArr[x][y].isDigged = true;
digJudge(gameLevel, msgArr, iRowNum, iLineNum);
}
//挖开方块周围边界至有数字方块函数
function digAmibientGrid(gameLevel, msgArr, x, y, iRowNum, iLineNum) {
msgArr[x][y].bCheck = true;
var arr = roundArray(x, y, iRowNum, iLineNum).slice(1),
curGridMsg;
for (var i = 0, len = arr.length; i < len; i++) {
digGrid(gameLevel, msgArr, arr[i].x, arr[i].y);
curGridMsg = msgArr[arr[i].x][arr[i].y];
if (!curGridMsg.isFlagged && !curGridMsg.bCheck && curGridMsg.figure === 0) {
digAmibientGrid(gameLevel, msgArr, arr[i].x, arr[i].y, iRowNum, iLineNum);
}
}
}
//自动探测按下函数
function autoExploreDown(gameLevel, msgArr, x, y, iRowNum, iLineNum, bFlag) {
var arr = roundArray(x, y, iRowNum, iLineNum),
curGridMsg;
for (var i = 0, len = arr.length; i < len; i++) {
curGridMsg = msgArr[arr[i].x][arr[i].y];
if (!curGridMsg.isDigged && !curGridMsg.isFlagged) {
gameLevel.children[arr[i].x].children[arr[i].y].className = bFlag ? "white" : "mc_cell";
}
}
}
//自动探测抬起函数
function autoExploreUp(gameLevel, msgArr, x, y, iRowNum, iLineNum) {
var arr = roundArray(x, y, iRowNum, iLineNum).slice(1),
curGridMsg;
for (var i = 0, len = arr.length; i < len; i++) {
curGridMsg = msgArr[arr[i].x][arr[i].y];
var curGridEle = gameLevel.children[arr[i].x].children[arr[i].y];
if (!curGridMsg.isDigged && !curGridMsg.isFlagged) {
if (!curGridMsg.isMine) {
digJudge(gameLevel, msgArr, iRowNum, iLineNum);
if (curGridMsg.figure === 0) {
curGridEle.className = "white";
digAmibientGrid(gameLevel, msgArr, arr[i].x, arr[i].y, iRowNum, iLineNum);
} else {
addFigureImg(curGridEle, curGridMsg.figure);
}
} else {
digAllGrid(gameLevel, msgArr, iRowNum, iLineNum);
curGridEle.className = "bomb0";
gameOver(false);
}
curGridMsg.isDigged = true;
}
}
}
//自动探测函数
function autoExplore(gameLevel, msgArr, x, y, iRowNum, iLineNum) {
if (msgArr[x][y].isDigged) {
if (msgArr[x][y].figure != 0 && numOfSurroundingFlag(msgArr, x, y, iRowNum, iLineNum) === msgArr[x][y].figure) {
autoExploreUp(gameLevel, msgArr, x, y, iRowNum, iLineNum);
} else {
autoExploreDown(gameLevel, msgArr, x, y, iRowNum, iLineNum, false);
var numOfGrid = msgArr[x][y].figure;
addFalseFigureImg(gameLevel.children[x].children[y], numOfGrid);
clearTimeout(msgArr[x][y].deferTimer);
msgArr[x][y].deferTimer = setTimeout(function () {
addFigureImg(gameLevel.children[x].children[y], numOfGrid);
}, 800);
}
} else {
autoExploreDown(gameLevel, msgArr, x, y, iRowNum, iLineNum, false);
}
}
//检测周围旗帜数量函数
function numOfSurroundingFlag(msgArr, x, y, iRowNum, iLineNum) {
var flagNum = 0,
arr = roundArray(x, y, iRowNum, iLineNum).slice(1);
for (var i = 0, len = arr.length; i < len; i++) {
if (msgArr[arr[i].x][arr[i].y].isFlagged) {
flagNum++;
}
}
return flagNum;
}
//游戏失败显示所有雷块函数
function digAllGrid(gameLevel, msgArr, iRowNum, iLineNum) {
var curGridEle;
for (var i = 0; i < iRowNum; i++) {
for (var j = 0; j < iLineNum; j++) {
curGridEle = gameLevel.children[i].children[j];
if (!msgArr[i][j].isDigged) {
if (msgArr[i][j].isMine && !msgArr[i][j].isFlagged) {
curGridEle.className = "bomb";
}
if (!msgArr[i][j].isMine && msgArr[i][j].isFlagged) {
curGridEle.className = "bomb_wrong";
}
}
}
}
}
//剩余雷数处理函数
function remainderMine(bFlag) {
var reMine = parseInt($gameMine.children[1].innerHTML);
reMine = bFlag ? reMine - 1 : reMine + 1;
$gameMine.children[1].innerHTML = reMine;
}
//游戏结束处理函数
function gameOver(isWin) {
bGameOver = true;
startMove($gameTime, upExPos);
startMove($gameMine, downExPos);
if (isWin) {
startMove($win, upPos);
startMove($overTime, upPos);
$overTime.children[1].innerHTML = $gameTime.children[0].innerHTML + ' 秒';
} else {
startMove($lose, upPos);
startMove($overTime, upPos);
$overTime.children[1].innerHTML = $gameTime.children[0].innerHTML + ' 秒';
}
startMove($overChoose, downPos);
}
//重置游戏清空数据函数
function clearData(gameLevel) {
var gameLevelArr = gameLevel.children,
row = gameLevelArr.length,
line = gameLevelArr[0].children.length,
i, j;
for (i = 0; i < row; i++) {
for (j = 0; j < line; j++) {
gameLevel.children[i].children[j].className = "mc_cell";
}
}
clearInterval(gameLevel.displayTimeTimer);
$gameTime.children[0].innerHTML = "0";
gameLevel.onmouseover = null;
gameLevel.onmouseout = null;
gameLevel.onmousedown = null;
gameLevel.onmouseup = null;
gameLevel.ondblclick = null;
}
//初始化游戏数据事件绑定函数
function initGame(gameLevel, gameStr, pos, rowNum, lineNum, mineNum) {
bGameOver = false;
msgArr = [];
mineArr = [];
curGameLevel = gameStr;
iMineNum = mineNum;
iRowNum = rowNum;
iLineNum = lineNum;
iGridNum = iRowNum * iLineNum;
iDigNum = 0;
timeStart = 0;
timeEnd = 0;
initMineArr(mineArr, iMineNum, iGridNum);
initMsgArr(msgArr, mineArr, iRowNum, iLineNum);
initFigure(msgArr, iRowNum, iLineNum);
var isMouseDown = false,
isOutside = false,
isMidMouseDown = false,
bFirstClick = true;
$gameMine.children[1].innerHTML = iMineNum;
//绑定游戏规则相关事件
//鼠标移入事件
gameLevel.onmouseover = function (e) {
if (bGameOver) {
return;
}
var event = e || global.event,
src = event.target || event.srcElement,
x = coordOfGrid(src).x,
y = coordOfGrid(src).y;
if (src.nodeName.toLowerCase() === "li") {
if (isMidMouseDown && !isOutside) {
autoExploreDown(gameLevel, msgArr, x, y, iRowNum, iLineNum, true);
} else {
if (!msgArr[x][y].isDigged) {
if (isMouseDown && !isOutside) {
src.className = "white";
} else {
if (msgArr[x][y].isFlagged) {
src.className = "flag_light";
} else if (msgArr[x][y].isMarked) {
src.className = "mark_light";
} else {
src.className = "mc_cell_light";
}
}
}
}
} else {
isOutside = true;
}
};
//鼠标移出事件
gameLevel.onmouseout = function (e) {
if (bGameOver) {
return;
}
var event = e || global.event,
src = event.target || event.srcElement,
x = coordOfGrid(src).x,
y = coordOfGrid(src).y;
if (src.nodeName.toLowerCase() === "li") {
if (isMidMouseDown) {
autoExploreDown(gameLevel, msgArr, x, y, iRowNum, iLineNum, false);
} else {
if (!msgArr[x][y].isDigged) {
if (msgArr[x][y].isFlagged) {
src.className = "flag";
} else if (msgArr[x][y].isMarked) {
src.className = "mark";
} else {
src.className = "mc_cell";
}
}
}
}
};
//鼠标按下事件
gameLevel.onmousedown = function (e) {
if (bGameOver) {
return;
}
var event = e || global.event,
src = event.target || event.srcElement,
x = coordOfGrid(src).x,
y = coordOfGrid(src).y,
index = msgArr[x][y].figure;
isOutside = false;
isMidMouseDown = false;
if (src.nodeName.toLowerCase() !== "li") {
return;
}
if (event.button === 0) {
if (!msgArr[x][y].isDigged && !msgArr[x][y].isFlagged) {
isMouseDown = true;
src.className = "white";
}
} else if (event.button === 2) {
if (!msgArr[x][y].isDigged) {
if (msgArr[x][y].isFlagged) {
src.className = "mark_light";
remainderMine(false);
msgArr[x][y].isFlagged = false;
msgArr[x][y].isMarked = true;
} else if (msgArr[x][y].isMarked) {
src.className = "mc_cell_light";
msgArr[x][y].isMarked = false;
} else {
src.className = "flag_light";
remainderMine(true);
msgArr[x][y].isFlagged = true;
}
}
} else {
isMidMouseDown = true;
autoExploreDown(gameLevel, msgArr, x, y, iRowNum, iLineNum, true);
}
};
//鼠标抬起事件
document.onmouseup = function (e) {
if (bGameOver) {
return;
}
var event = e || global.event,
src = event.target || event.srcElement,
x = coordOfGrid(src).x,
y = coordOfGrid(src).y,
index = msgArr[x][y].figure;
if (src.nodeName.toLowerCase() !== "li") {
isOutside = true;
return;
}
if (event.button === 0) {
isMouseDown = false;
if (bFirstClick) {
timeStart = new Date().getTime();
bFirstClick = false;
clearInterval(gameLevel.displayTimeTimer);
gameLevel.displayTimeTimer = setInterval(function () {
timeEnd = new Date().getTime();
$gameTime.children[0].innerHTML = parseInt((timeEnd - timeStart) / 1000);
}, 50);
}
if (!msgArr[x][y].isDigged && !msgArr[x][y].isFlagged) {
msgArr[x][y].isDigged = true;
if (msgArr[x][y].isMine) {
src.className = "bomb0";
digAllGrid(gameLevel, msgArr, iRowNum, iLineNum);
gameOver(false);
} else if (index !== 0) {
addFigureImg(src, index);
digJudge(gameLevel, msgArr, iRowNum, iLineNum);
} else {
src.className = "white";
digJudge(gameLevel, msgArr, iRowNum, iLineNum);
digAmibientGrid(gameLevel, msgArr, x, y, iRowNum, iLineNum);
}
}
} else if (event.button === 1) {
isMidMouseDown = false;
autoExplore(gameLevel, msgArr, x, y, iRowNum, iLineNum);
}
};
//鼠标双击事件
gameLevel.ondblclick = function (e) {
if (bGameOver) {
return;
}
var event = e || global.event,
src = event.target || event.srcElement,
x = coordOfGrid(src).x,
y = coordOfGrid(src).y;
autoExplore(gameLevel, msgArr, x, y, iRowNum, iLineNum);
};
};
//阻止浏览器默认拖拽事件
document.onmousemove = function (e) {
cancelHandler(e);
};
//阻止浏览器默认右键菜单事件
document.oncontextmenu = function (e) {
cancelHandler(e);
};
//绑定按钮点击事件
$btnStart.onclick = function () {
startMove($mcStart, upExPos);
startMove($mcLevel, midPos);
};
$btnPri.onclick = function () {
startMove($mcLevel, upExPos);
startMove($priGame, priLevelPos);
startMove($gameTime, upPos);
startMove($gameMine, downPos);
initGame($priGame, "pri", priLevelPos, 9, 9, 10);
};
$btnMid.onclick = function () {
startMove($mcLevel, upExPos);
startMove($midGame, highLevelPos);
startMove($gameTime, upPos);
startMove($gameMine, downPos);
initGame($midGame, "mid", highLevelPos, 16, 16, 40);
};
$btnExp.onclick = function () {
startMove($mcLevel, upExPos);
startMove($expGame, highLevelPos);
startMove($gameTime, upPos);
startMove($gameMine, downPos);
initGame($expGame, "exp", highLevelPos, 16, 30, 99);
};
$replay.onclick = function () {
startMove($win, upExPos);
startMove($lose, upExPos);
startMove($overTime, upExPos);
startMove($overChoose, downExPos);
startMove($gameTime, upPos);
startMove($gameMine, downPos);
switch (curGameLevel) {
case "pri":
clearData($priGame);
initGame($priGame, "pri", priLevelPos, 9, 9, 10);
break;
case "mid":
clearData($midGame);
initGame($midGame, "mid", highLevelPos, 16, 16, 40);
break;
case "exp":
clearData($expGame);
initGame($expGame, "exp", highLevelPos, 16, 30, 99);
break;
}
};
$reselect.onclick = function () {
startMove($win, upExPos);
startMove($lose, upExPos);
startMove($overTime, upExPos);
startMove($overChoose, downExPos);
switch (curGameLevel) {
case "pri":
clearData($priGame);
startMove($priGame, downExPos);
break;
case "mid":
clearData($midGame);
startMove($midGame, downExPos);
break;
case "exp":
clearData($expGame);
startMove($expGame, downExPos);
break;
}
startMove($mcLevel, midPos);
};
} (window));