對(duì)于10年前的人來說,掃雷肯定是家喻戶曉,由于當(dāng)時(shí)的科技并不是很發(fā)達(dá),大家對(duì)于電腦游戲的了解,可能都是從掃雷開始的,今天就交大家一種用js原生代碼寫一個(gè)簡(jiǎn)單的掃雷游戲,話不多說,直接上干貨:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
<!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" >開始</ span > < span class = "restart" >重開</ 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 = [],// 用來存放地雷坐標(biāo)的數(shù)組 sum = col*row,// 棋盤所有格子的總數(shù) openGz = 0,// 已經(jīng)點(diǎn)開的格子的數(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)開始!'); return; } if(e.target.isOpen){ alert('這個(gè)格子已經(jīng)翻過了,換個(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)擊開始游戲 flag = true;// 棋盤可以被點(diǎn)擊 if(time>0){// 判斷開始鍵是否已經(jīng)被點(diǎn)過,防止重復(fù)點(diǎn)擊 alert('游戲已經(jīng)開始了,不要再點(diǎn)開始了') return } countTime()//開始計(jì)時(shí) } restart.onclick = function(){//點(diǎn)擊開始游戲 flag = false;// flag置為false,棋盤格子變成不可點(diǎn)擊狀態(tài) createQp();// 畫棋盤 } box.onclick = function(e){//點(diǎ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)開始 alert('請(qǐng)先點(diǎn)開始!') return } var x = t.dataset.x - 0 ,y = t.dataset.y - 0; // console.log(x,y); if(t.isOpen){ alert('這個(gè)格子已經(jīng)翻過了,換個(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){//改變棋盤規(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();// 重新畫棋盤 }; function createQp(){// 創(chuàng)建棋盤 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;// 將拼接的棋盤內(nèi)容添加到棋盤中 count = 0;// 計(jì)時(shí)重置為0 sum = row*col;// 重置格子的總數(shù) openGz = 0;// 重置已經(jīng)點(diǎn)開的格子的數(shù)量 passTime.innerHTML = count; // 時(shí)間設(shè)置為count restNum = leiNum;//重置剩余的雷的數(shù)量 leftLei.innerHTML = restNum; clearInterval(time);// 清除定時(shí)器 time = 0;// 定時(shí)器變量的值置為 0 createLei(); } function countTime(){// 開始計(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ì)上,說明 [x,y] 已經(jīng)存在于 arr 里, return i;// 返回[x,y] 在 arr中的索引 } } if(i == arr.length){// 當(dāng) 循環(huán)遍歷一遍也沒在arr中找到與 [x,y] 相同的坐標(biāo)時(shí),說明 [x,y] 不在arr 里 return -1;// 返回 -1; } } function boom(){// boom var ul = $('.row','l');//獲取棋盤里所有的行 for(var i = 0 ;i<leiList.length;i++){ var li = ul [leiList[i][0]].querySelectorAll('li')[leiList[i][1]];//通過索引去獲取行里具體的li li.style.background = 'red' } } function testLei(x,y){ var num = 0 ; // 聲明一個(gè)num用來累計(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)擊的格子周圍八個(gè)格子里的雷 num++; } } var ul = $('.row','l'); var li = ul [x].querySelectorAll('li')[y];// 通過索引獲取當(dāng)前被點(diǎn)擊的格子 li.innerHTML = num ;// 把格子的內(nèi)容換成雷的數(shù)量 li.isOpen = true ;// 給當(dāng)前格子加一個(gè)屬性 isOpen,表示當(dāng)前格子已經(jīng)被點(diǎn)開了 openGz++; li.style.background = '#fff' ; if(num>0){ li.style.color = color[num-1];// 把代表雷的數(shù)量的數(shù)字換一個(gè)顏色 } if(num == 0){// 如果當(dāng)前格子周圍沒有雷 li.innerHTML = '';// for(var a = x-1;a<=x+1;a++){// for(var b = y-1;b<=y+1;b++){// 遍歷當(dāng)前格子周圍八個(gè)格子 var ul = $('ul','l'); if(a>= 0 && a< row && b>=0 && b< col ){// 保證要遍歷的格子坐標(biāo)在棋盤之內(nèi) var dom = ul [a].querySelectorAll('li')[b];// 通過坐標(biāo)獲取到具體的 li if(!dom.isOpen && !dom.isMark){// 判斷當(dāng)前的li格子是否已經(jīng)被點(diǎn)開了,如果還沒有被點(diǎn)開,遞歸查詢?cè)摳褡又車袔最w雷 testLei(a,b) } } } } } } createQp(); </script> </ body > </ html > |
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/weixin_48156531/article/details/111951871