分享自己用JS做的掃雷小游戲
引用了jQuery,節(jié)省了很多鼠標(biāo)點(diǎn)擊上的判斷。界面顯然都是照搬Windows的掃雷啦,詳細(xì)的內(nèi)容注釋里都有,我就不啰嗦啦~
先上截圖~
引用了jQuery,節(jié)省了很多鼠標(biāo)點(diǎn)擊上的判斷
界面顯然都是照搬Windows的掃雷啦
詳細(xì)的內(nèi)容注釋里都有,我就不啰嗦啦~
JS部分
var mineArray, //地雷數(shù)組 lastNum, //剩余雷數(shù) countNum, //未被揭開(kāi)的方塊數(shù) inGame = 0, //游戲狀態(tài),0為結(jié)束,1為進(jìn)行中,2為初始化完畢但未開(kāi)始 startTime; //開(kāi)始時(shí)間 //以下操作1表示揭開(kāi)一個(gè)方塊,操作2表示標(biāo)記一個(gè)小旗,操作3表示標(biāo)記一個(gè)問(wèn)號(hào),操作4表示若某個(gè)方塊周圍的地雷全都標(biāo)記完,則將其周圍剩下的方塊挖開(kāi) $(function(){ $('#main').mouseup(function(e) { var clicked = $(e.target), id = clicked.attr('id'), cX = parseInt(id.substring(1, id.indexOf('-'))), //所點(diǎn)擊方格的X坐標(biāo) cY = parseInt(id.substring(id.indexOf('-') + 1)); //所點(diǎn)擊方格的Y坐標(biāo) if(inGame == 1) { if(e.which == 1) { if(clicked.hasClass('hidden') && !clicked.hasClass('flag')) { openBlock(cX,cY); //左鍵點(diǎn)擊未揭開(kāi)且未插旗方塊即執(zhí)行操作1 } else if(!clicked.hasClass('hidden')) { openNearBlock(cX,cY); //由于同時(shí)點(diǎn)擊左右鍵實(shí)現(xiàn)起來(lái)比較麻煩,所以改成用點(diǎn)擊左鍵實(shí)現(xiàn)操作4 } } else if(e.which == 3 && clicked.hasClass('hidden')) { //右鍵點(diǎn)擊操作2,如果允許使用問(wèn)號(hào)標(biāo)記,則可執(zhí)行操作3 if(clicked.hasClass('flag')) { clicked.removeClass('flag'); if($('#check').attr('checked')) clicked.addClass('check'); lastNum ++; countNum ++; } else if(clicked.hasClass('check')) { clicked.removeClass('check'); } else { clicked.addClass('flag'); lastNum --; countNum --; } $('#lastnum').text(lastNum); } if(lastNum == countNum) endGame(1); //因?yàn)樽詈笫O碌姆綁K均為雷時(shí)應(yīng)直接結(jié)束游戲,因此設(shè)置為剩余雷數(shù)和未被揭開(kāi)的方塊數(shù)相等的時(shí)候結(jié)束游戲 } else if(inGame == 2) { if(e.which == 1) { //初始化完畢后只允許點(diǎn)擊左鍵開(kāi)始游戲 openBlock(cX,cY); inGame = 1; var now = new Date(); startTime = now.getTime(); timer(); } } }); $('#main').bind('contextmenu', function(){ return false; }); //阻止默認(rèn)右擊事件 }); //初始化 function init(x, y, mine) { countNum = x * y; inGame = 2; lastNum = mine; mineArray = new Array(y + 2); $.each(mineArray, function(key) { mineArray[key] = new Array(x + 2); }); for(var i = 1; i <= y; i ++) { for(var j = 1; j <= x; j ++) { mineArray[i][j] = 0; } } while(mine > 0) { //隨機(jī)布雷,-1為有雷 var i = Math.ceil(Math.random() * y); var j = Math.ceil(Math.random() * x); if(mineArray[i][j] != -1) { mineArray[i][j] = -1; mine --; } } for(var i = 1; i <= y; i ++) { //遍歷地雷數(shù)組,統(tǒng)計(jì)每個(gè)格子四周地雷的數(shù)量 for(var j = 1; j <= x; j ++) { if(mineArray[i][j] != -1) { if(i > 1 && j > 1 && mineArray[i - 1][j - 1] == -1) mineArray[i][j] ++; if(i > 1 && mineArray[i - 1][j] == -1) mineArray[i][j] ++; if(i > 1 && j < x && mineArray[i - 1][j + 1] == -1) mineArray[i][j] ++; if(j < x && mineArray[i][j + 1] == -1) mineArray[i][j] ++; if(i < y && j < x && mineArray[i + 1][j + 1] == -1) mineArray[i][j] ++; if(i < y && mineArray[i + 1][j] == -1) mineArray[i][j] ++; if(i < y && j > 1 && mineArray[i + 1][j - 1] == -1) mineArray[i][j] ++; if(j > 1 && mineArray[i][j - 1] == -1) mineArray[i][j] ++; } } } var block = ''; for(var i = 1, row = mineArray.length - 1; i < row; i ++) { for(var j = 1, col = mineArray[0].length - 1; j < col; j ++) { block += '<div id="b' + i + '-' + j + '" style="left:' + (j - 1) * 20 + 'px;top:' + (i - 1) * 20 + 'px;" class="hidden"></div>'; } } $('#main').html(block).width(x * 20 + 1).height(y * 20 + 1).show(); //繪圖 $('#warning').html(''); $('#submenu').show(); $('#lastnum').text(lastNum); } //揭開(kāi)方塊 function openBlock(x, y) { var current = $('#b' + x + '-' + y); if(mineArray[x][y] == -1) { if(inGame == 1) { //觸雷時(shí)如游戲進(jìn)行中,則失敗結(jié)束游戲 current.addClass('cbomb'); endGame(); } else if(inGame == 2) { //如游戲初始化后還未開(kāi)始,則重新初始化地雷陣,再揭開(kāi)此方塊,以保證第一次點(diǎn)擊不觸雷 init(mineArray[0].length - 2, mineArray.length - 2, lastNum); openBlock(x, y); } else { //游戲結(jié)束時(shí)需揭開(kāi)全部方塊,標(biāo)記地雷位置 if(!current.hasClass('flag')) current.addClass('bomb'); } } else if(mineArray[x][y] > 0) { if(current.hasClass('flag')) { //若在無(wú)雷的方塊上標(biāo)記了小旗,如果周圍的廣場(chǎng)執(zhí)行操作4時(shí)波及到此方塊,則觸發(fā)失敗結(jié)束游戲 current.addClass('wrong'); if(inGame) endGame(); } else { current.html(mineArray[x][y]).addClass('num' + mineArray[x][y]).removeClass('hidden'); //顯示周邊的地雷數(shù)量 if(current.hasClass('check')) current.removeClass('check'); if(inGame) countNum --; } } else { if(current.hasClass('flag')) { //同上 current.addClass('wrong'); if(inGame) endGame(); } else { current.removeClass('hidden'); if(current.hasClass('check')) current.removeClass('check'); if(inGame) { //點(diǎn)擊到周邊無(wú)雷的方塊時(shí),自動(dòng)揭開(kāi)周圍方塊 countNum --; var row = mineArray.length - 2, col = mineArray[0].length - 2; if(x > 1 && y > 1 && $('#b' + (x - 1) + '-' + (y - 1)).hasClass('hidden')) openBlock(x - 1, y - 1); if(x > 1 && $('#b' + (x - 1) + '-' + y).hasClass('hidden')) openBlock(x - 1, y); if(x > 1 && y < col && $('#b' + (x - 1) + '-' + (y + 1)).hasClass('hidden')) openBlock(x - 1, y + 1); if(y < col && $('#b' + x + '-' + (y + 1)).hasClass('hidden')) openBlock(x, y + 1); if(x < row && y < col && $('#b' + (x + 1) + '-' + (y + 1)).hasClass('hidden')) openBlock(x + 1, y + 1); if(x < row && $('#b' + (x + 1) + '-' + y).hasClass('hidden')) openBlock(x + 1, y); if(x < row && y > 1 && $('#b' + (x + 1) + '-' + (y - 1)).hasClass('hidden')) openBlock(x + 1, y - 1); if(y > 1 && $('#b' + x + '-' + (y - 1)).hasClass('hidden')) openBlock(x, y - 1); } } } } //揭開(kāi)格子鄰近確認(rèn)無(wú)雷的方塊 function openNearBlock(x, y) { var flagNum = 0, hiddenNum = 0; for(i = x - 1; i < x + 2; i ++) { for(j = y - 1; j < y + 2; j ++) { if(mineArray[i][j] != undefined) { if($('#b' + i + '-' + j).hasClass('flag')) flagNum ++; //統(tǒng)計(jì)方塊周圍的旗幟數(shù)和未揭開(kāi)的方塊數(shù) if($('#b' + i + '-' + j).hasClass('hidden')) hiddenNum ++; } } } if(flagNum == mineArray[x][y] && hiddenNum > flagNum) { //旗幟數(shù)和雷數(shù)相等且有未揭開(kāi)方塊且未插旗的方塊時(shí),則揭開(kāi)它 for(i = x - 1; i < x + 2; i ++) { for(j = y - 1; j < y + 2; j ++) { if(mineArray[i][j] >= 0 && $('#b' + i + '-' + j).hasClass('hidden')) openBlock(i, j); } } } } //計(jì)時(shí) function timer(){ if(inGame == 1) { //只在游戲進(jìn)行中計(jì)時(shí) var now = new Date(), ms = now.getTime(); $('#time').text(Math.ceil((ms - startTime) / 1000)); if(inGame == 1) setTimeout(function() { timer(); }, 500); } else if(inGame == 2) { $('#time').text('0'); } } //結(jié)束游戲 function endGame(isWin) { inGame = 0; for(var i = 1, row = mineArray.length - 1; i < row; i ++) { for(var j = 1, col = mineArray[0].length - 1; j < col; j ++) { if(isWin) { if($('#b' + i + '-' + j).hasClass('hidden') && !$('#b' + i + '-' + j).hasClass('flag')) $('#b' + i + '-' + j).addClass('flag'); lastNum = 0; $('#lastnum').text(lastNum); } else { openBlock(i, j); } } } $('#warning').text(isWin ? 'You Win!' : 'You Lose!'); }
HTML部分
<div id="menu"> <a href="javascript:;" onclick="init(10,10,10);">初級(jí)</a> <a href="javascript:;" onclick="init(16,16,40);">中級(jí)</a> <a href="javascript:;" onclick="init(30,16,99);">高級(jí)</a> <input type="checkbox" id="check" /><label for="check">是否使用標(biāo)記(?)</label> </div> <div id="submenu"> 剩余雷數(shù):<span id="lastnum"></span> 時(shí)間:<span id="time"></span>秒 <span id="warning"></span> </div> <div id="main"></div>
CSS部分
body{background:#fff;font-size:14px;} #submenu{display:none;} #warning{color:#ff0000;} #main{background:#ddd;border:1px solid #888;display:none;position:relative;} #main div{border:1px solid #888;font-weight:bold;height:19px;height:21px\9;line-height:18px;cursor:default;position:absolute;text-align:center;width:19px;width:21px\9;} .hidden{background:url(mine.gif) 0 0;} .flag{background:url(mine.gif) -19px 0;} .check{background:url(mine.gif) -38px 0;} .bomb{background:url(mine.gif) -57px 0;} .cbomb{background:url(mine.gif) -57px 0 #ff0000;} .wrong{background:url(mine.gif) -76px 0;} .num1{color:#0000ff;} .num2{color:#008000;} .num3{color:#ff0000;} .num4{color:#000080;} .num5{color:#800000;} .num6{color:#008080;} .num7{color:#000000;} .num8{color:#808080;}
以上所述是小編給大家分享自己用JS做的掃雷小游戲,希望對(duì)大家有所幫助。
相關(guān)文章
一個(gè)JavaScript獲取元素當(dāng)前高度的實(shí)例
這篇文章主要為大家介紹了一個(gè)JavaScript獲取元素當(dāng)前高度的實(shí)例,比較實(shí)用,建議新手朋友們可以看看2014-10-10基于JavaScript判斷兩個(gè)對(duì)象內(nèi)容是否相等
這篇文章主要介紹了基于JavaScript判斷兩個(gè)對(duì)象內(nèi)容是否相等,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01詳解webpack中的hash、chunkhash、contenthash區(qū)別
這篇文章主要介紹了詳解webpack中的hash、chunkhash、contenthash區(qū)別,詳細(xì)的介紹了hash、chunkhash、contenthash的用法和區(qū)別,有興趣的可以了解一下2018-01-01前端學(xué)習(xí)筆記style,currentStyle,getComputedStyle的用法與區(qū)別
這篇文章主要介紹了前端學(xué)習(xí)筆記style,currentStyle,getComputedStyle的用法與區(qū)別,需要的朋友可以參考下2016-05-05JavaScript時(shí)間對(duì)象Date內(nèi)置構(gòu)造函數(shù)操作實(shí)例
這篇文章主要為大家介紹了JavaScript時(shí)間對(duì)象Date內(nèi)置構(gòu)造函數(shù)操作實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05