基于JavaScript實(shí)現(xiàn)簡(jiǎn)單掃雷游戲
對(duì)于10年前的人來(lái)說(shuō),掃雷肯定是家喻戶(hù)曉,由于當(dāng)時(shí)的科技并不是很發(fā)達(dá),大家對(duì)于電腦游戲的了解,可能都是從掃雷開(kāi)始的,今天就交大家一種用js原生代碼寫(xiě)一個(gè)簡(jiǎn)單的掃雷游戲,話不多說(shuō),直接上干貨:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
li{
list-style: none;
}
.box{
border: 1px solid #666;
position: fixed;
width: 300px;
height: 350px;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
.btn-group{
display: flex;
height: 50px;
line-height: 50px;
text-align: center;
justify-content: space-evenly;
font-size: 12px;
}
.row{
height: 30px;
line-height: 30px;
text-align: center;
display: flex;
}
.col{
flex-shrink: 0;
/* flex-shrink 是否允許縮小 */
flex-grow: 0;
/* flex-grow 是否允許放大 */
width: 30px;
height: 30px;
border: 1px solid #666;
background-color: #ccc;
box-sizing: border-box;
}
</style>
</head>
<body>
<div class="box">
<div class="qipan">
</div>
<div class="btn-group">
<div class="btn-item">
<span class="item-name">時(shí)間</span>
<span class="item-value passTime">000</span>
</div>
<div class="btn-item">
<span class="item-name">剩余雷數(shù)</span>
<span class="item-value leftLei">10</span>
</div>
<div class="btn-item">
<select class="level">
<option value="1">初級(jí)</option>
<option value="2">中級(jí)</option>
<option value="3">高級(jí)</option>
</select>
</div>
<div class="btn-item">
<span class="start">開(kāi)始</span>
<span class="restart">重開(kāi)</span>
</div>
</div>
</div>
<script>
function $(s,t){
if(t == 'l'){
return document.querySelectorAll(s)
}else{
return document.querySelector(s)
}
}
var qipan = $('.qipan'),
box = $('.box'),
level = $('.level'),
leftLei = $('.leftLei'),
start = $('.start'),
restart = $('.restart'),
passTime = $('.passTime')
;
var row = 10,// 行數(shù)
col = 10,// 列數(shù)
leiNum = 10,// 雷數(shù)
restNum = 10,//剩余的雷數(shù)
flag = false,// 格子是否可以被點(diǎn)擊
time,//計(jì)時(shí)器的名字
count = 0,// 計(jì)時(shí)的秒數(shù)
leiList = [],// 用來(lái)存放地雷坐標(biāo)的數(shù)組
sum = col*row,// 棋盤(pán)所有格子的總數(shù)
openGz = 0,// 已經(jīng)點(diǎn)開(kāi)的格子的數(shù)量
color = ['rgba(0,0,255,.6)','rgba(0,255,0,.6)','red','blue','yellow','pink','auqa','black']
;
window.oncontextmenu = function(e){
e.preventDefault();
if(!flag){
alert('請(qǐng)先點(diǎn)開(kāi)始!');
return;
}
if(e.target.isOpen){
alert('這個(gè)格子已經(jīng)翻過(guò)了,換個(gè)格子標(biāo)記');
return
}
if(e.target.localName == 'li'){
if(e.target.isMark){
e.target.isMark = false;
e.target.innerHTML = '';
restNum++;
}else{
e.target.isMark = true;
e.target.innerHTML = '▲';
e.target.style.color = 'red';
restNum--;
}
leftLei.innerHTML = restNum
}
}
start.onclick = function(){//點(diǎn)擊開(kāi)始游戲
flag = true;// 棋盤(pán)可以被點(diǎn)擊
if(time>0){// 判斷開(kāi)始鍵是否已經(jīng)被點(diǎn)過(guò),防止重復(fù)點(diǎn)擊
alert('游戲已經(jīng)開(kāi)始了,不要再點(diǎn)開(kāi)始了')
return
}
countTime()//開(kāi)始計(jì)時(shí)
}
restart.onclick = function(){//點(diǎn)擊開(kāi)始游戲
flag = false;// flag置為false,棋盤(pán)格子變成不可點(diǎn)擊狀態(tài)
createQp();// 畫(huà)棋盤(pán)
}
box.onclick = function(e){//點(diǎn)擊棋盤(pán)的格子
var t = e.target;
if(t.localName == 'li'){// 只有當(dāng)點(diǎn)擊的格子是li的時(shí)候才會(huì)繼續(xù)往下判斷
if(!flag){// 如果當(dāng)前不允許點(diǎn)擊,提示先點(diǎn)開(kāi)始
alert('請(qǐng)先點(diǎn)開(kāi)始!')
return
}
var x = t.dataset.x - 0 ,y = t.dataset.y - 0;
// console.log(x,y);
if(t.isOpen){
alert('這個(gè)格子已經(jīng)翻過(guò)了,換個(gè)格子翻');
return
}
if(t.isMark){
alert('這個(gè)格子已經(jīng)標(biāo)記了,換個(gè)格子翻');
return
}
if(isInArray(x,y,leiList) != -1 ){
flag = false;
clearInterval(time);
count = 0;
passTime.innerHTML = count;
boom();
alert('你輸了')
}else{
testLei(x,y);
if(leiNum == sum - openGz){
flag = false;
boom();
clearInterval(time);
alert('你贏了');
}
}
}
}
level.onchange = function(){
var v = this.value;//獲取改變后的level
if(v == 1){//改變棋盤(pán)規(guī)格及雷的數(shù)量
row = 10;
col = 10;
leiNum = 10;
}else if(v == 2){
row = 16;
col = 16;
leiNum = 40;
}else if(v == 3){
row = 16;
col = 30;
leiNum = 99;
}
createQp();// 重新畫(huà)棋盤(pán)
};
function createQp(){// 創(chuàng)建棋盤(pán)
var str = '';
for(var i = 0;i<row;i++){// 行數(shù)
str += '<ul class="row">'
for(var j = 0;j<col;j++){// 列數(shù)
str+='<li class="col" data-x="'+i+'" data-y="'+j+'"></li>'
}
str += '</ul>'
}
box.style.width = col * 30 +'px';//修改box的寬度
box.style.height = row * 30 + 50 +'px';// 修改box的高度
leftLei.innerHTML = leiNum;// 修改剩余雷數(shù)
qipan.innerHTML = str;// 將拼接的棋盤(pán)內(nèi)容添加到棋盤(pán)中
count = 0;// 計(jì)時(shí)重置為0
sum = row*col;// 重置格子的總數(shù)
openGz = 0;// 重置已經(jīng)點(diǎn)開(kāi)的格子的數(shù)量
passTime.innerHTML = count; // 時(shí)間設(shè)置為count
restNum = leiNum;//重置剩余的雷的數(shù)量
leftLei.innerHTML = restNum;
clearInterval(time);// 清除定時(shí)器
time = 0;// 定時(shí)器變量的值置為 0
createLei();
}
function countTime(){// 開(kāi)始計(jì)時(shí)
time = setInterval(function(){
count++;
passTime.innerHTML = count;
},1000)
}
function createLei(){// 創(chuàng)建地雷
leiList = [];// 把地雷的坐標(biāo)先清空
for(var i = 0;i<leiNum;i++){
var x = parseInt(Math.random()*row),//
y = parseInt(Math.random()*col);//
if(isInArray(x,y,leiList) == -1){// 如果 x,y組成的坐標(biāo)[x,y] 不在leiList里
leiList.push([x,y])// 把 [x,y] push進(jìn) leiList里
}else{// x,y組成的坐標(biāo) [x,y] 已經(jīng)在 leiList里了
i-- // 重新取一次隨機(jī)坐標(biāo)
}
}
}
// arr = [[0,0],[1,1],[2,2],...]
function isInArray(x,y,arr){// 判斷 x,y 組成的坐標(biāo) [x,y] 在不在數(shù)組 arr 里
for(var i = 0;i<arr.length;i++){// 遍歷arr的每一個(gè)元素
if(x == arr[i][0] && y == arr[i][1]){// 將 x與arr[i]的第0個(gè)元素對(duì)比,將 y 與 arr[i]的第1個(gè)元素對(duì)比,如果能對(duì)上,說(shuō)明 [x,y] 已經(jīng)存在于 arr 里,
return i;// 返回[x,y] 在 arr中的索引
}
}
if(i == arr.length){// 當(dāng) 循環(huán)遍歷一遍也沒(méi)在arr中找到與 [x,y] 相同的坐標(biāo)時(shí),說(shuō)明 [x,y] 不在arr 里
return -1;// 返回 -1;
}
}
function boom(){// boom
var ul = $('.row','l');//獲取棋盤(pán)里所有的行
for(var i = 0;i<leiList.length;i++){
var li = ul[leiList[i][0]].querySelectorAll('li')[leiList[i][1]];//通過(guò)索引去獲取行里具體的li
li.style.background = 'red'
}
}
function testLei(x,y){
var num = 0; // 聲明一個(gè)num用來(lái)累計(jì)雷的數(shù)量
for(var i = 0;i<leiList.length;i++){// 遍歷所有的雷的坐標(biāo)
if(Math.abs(x - leiList[i][0]) <2 && Math.abs(y - leiList[i][1])<2){// 找到在當(dāng)前點(diǎn)擊的格子周?chē)藗€(gè)格子里的雷
num++;
}
}
var ul = $('.row','l');
var li = ul[x].querySelectorAll('li')[y];// 通過(guò)索引獲取當(dāng)前被點(diǎn)擊的格子
li.innerHTML = num;// 把格子的內(nèi)容換成雷的數(shù)量
li.isOpen = true;// 給當(dāng)前格子加一個(gè)屬性 isOpen,表示當(dāng)前格子已經(jīng)被點(diǎn)開(kāi)了
openGz++;
li.style.background = '#fff';
if(num>0){
li.style.color = color[num-1];// 把代表雷的數(shù)量的數(shù)字換一個(gè)顏色
}
if(num == 0){// 如果當(dāng)前格子周?chē)鷽](méi)有雷
li.innerHTML = '';//
for(var a = x-1;a<=x+1;a++){//
for(var b = y-1;b<=y+1;b++){// 遍歷當(dāng)前格子周?chē)藗€(gè)格子
var ul = $('ul','l');
if(a>= 0 && a<row && b>=0 && b<col){// 保證要遍歷的格子坐標(biāo)在棋盤(pán)之內(nèi)
var dom = ul[a].querySelectorAll('li')[b];// 通過(guò)坐標(biāo)獲取到具體的 li
if(!dom.isOpen && !dom.isMark){// 判斷當(dāng)前的li格子是否已經(jīng)被點(diǎn)開(kāi)了,如果還沒(méi)有被點(diǎn)開(kāi),遞歸查詢(xún)?cè)摳褡又車(chē)袔最w雷
testLei(a,b)
}
}
}
}
}
}
createQp();
</script>
</body>
</html>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 原生js實(shí)現(xiàn)自定義難度的掃雷游戲
- js+canvas實(shí)現(xiàn)簡(jiǎn)單掃雷小游戲
- 通過(guò)javascript實(shí)現(xiàn)掃雷游戲代碼實(shí)例
- HTML+JavaScript實(shí)現(xiàn)掃雷小游戲
- JavaScript版經(jīng)典游戲之掃雷游戲完整示例【附demo源碼下載】
- 分享自己用JS做的掃雷小游戲
- 使用純javascript實(shí)現(xiàn)經(jīng)典掃雷游戲
- JavaScript制作windows經(jīng)典掃雷小游戲
- javascript 掃雷游戲
- js實(shí)現(xiàn)經(jīng)典掃雷游戲
相關(guān)文章
JS實(shí)現(xiàn)的論壇Ajax打分效果完整實(shí)例
這篇文章主要介紹了JS實(shí)現(xiàn)的論壇Ajax打分效果,以完整實(shí)例形式分析了JavaScript響應(yīng)鼠標(biāo)事件動(dòng)態(tài)操作頁(yè)面元素樣式的相關(guān)技巧,需要的朋友可以參考下2015-10-10
BootStrap智能表單實(shí)戰(zhàn)系列(九)表單圖片上傳的支持
這篇文章主要介紹了BootStrap智能表單實(shí)戰(zhàn)系列(九)表單圖片上傳的支持,介紹如何在生成表單后,可以支持上傳圖片后可以及時(shí)預(yù)覽圖片的功能,需要的朋友可以參考下2016-06-06
JS實(shí)現(xiàn)模態(tài)框拖拽動(dòng)態(tài)效果
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)模態(tài)框拖拽動(dòng)態(tài)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
純JavaScript實(shí)現(xiàn)櫻花飄落效果的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何純JavaScript實(shí)現(xiàn)櫻花飄落效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04
JavaScript數(shù)組去重的3種方法和代碼實(shí)例
這篇文章主要介紹了JavaScript數(shù)組去重的3種方法和代碼實(shí)例,本文直接給出實(shí)例代碼,需要的朋友可以參考下2015-07-07
微信小程序 如何引入外部字體庫(kù)iconfont的圖標(biāo)
這篇文章主要為大家詳細(xì)介紹了微信小程序引入外部字體庫(kù)iconfont圖標(biāo)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
pageGroup.js實(shí)現(xiàn)分頁(yè)功能
這篇文章主要為大家詳細(xì)介紹了pageGroup.js實(shí)現(xiàn)分頁(yè)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07

