利用原生js做了一个扫雷

之前看了别人用js做的一个扫雷游戏,但是发现有一堆bug,还不能配置!!

想了一下,自己也做了一个原生js的扫雷游戏,目前还没发现bug,欢迎指出!

游戏主体稍微复杂点的就是递归做扩散(也还好)!

设置了可配置的棋牌和雷数量,并对对输入进行验证!

HTML  没啥好看的!

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
 7     <title>Document</title>
 8     <link rel="stylesheet" href="demo.css">
 9     <script src="demo.js"></script>
10 </head>
11 <body>
12     <div class="control">
13         <div class="configure">
14             <div class="col">
15                 <span>行数:</span><input type="text" id="col" placeholder="默认为10" value="">
16             </div>
17             <div class="row">
18                 <span>列数:</span><input type="text" id="row" placeholder="默认为10" value="">
19             </div>
20             <div class="lei">
21                 <span>地雷:</span><input type="text" id="lei" placeholder="默认为10" value="">
22             </div>
23         </div>
24         <div class="dis">
25             <button id="begin">开始游戏</button>
26             <button id="again">重新开始</button>
27             <span class="save">安全区</span>
28             <span class="lei">地雷</span>
29             <span class="flag">地雷标记</span>
30         </div>
31         <div class="sore">
32             <div class="time">TIME:<span id="time"></span></div>
33             <div class="residual">剩余地雷:<span id="leave"></span></div>
34         </div>
35     </div>
36     <div id="mysaolei"></div>
37 </body>
38 </html>
HTML

css 就这点!

  1 * {
  2     margin: 0;
  3     padding: 0;
  4     list-style: none
  5 }
  6 .control {
  7     width: 1000px;
  8     height: 150px;
  9     position: relative;
 10     left: 50%;
 11     transform: translateX(-50%);
 12     margin-top: 10px;
 13     border: 1px solid silver;
 14     border-radius: 2px;
 15 }
 16 .control .configure {
 17     width: 300px;
 18     height: 150px;
 19     float: left;
 20 }
 21 .control .configure div{
 22     margin-top: 5px;
 23     height: 40px;
 24     line-height: 40px;
 25 }
 26 .control .configure div span {
 27     font-size: 25px;
 28     font-weight: 700;
 29     margin-left: 10px;
 30 }
 31 .control .configure div input {
 32     width: 100px;    
 33     font-size: 20px;
 34     text-align: center;
 35 }
 36 .control .dis {
 37     position: absolute;
 38     width: 300px;
 39     left: 50%;
 40     margin-left: -150px;
 41 }
 42 .control .dis button {
 43     position: absolute;
 44     width: 200px;
 45     height: 80px;
 46     border-radius: 40px;
 47     outline: 0px;
 48     font-size: 35px;
 49     font-weight: 700;
 50     border: 1px solid silver;
 51     margin-top: 10px;
 52     margin-left: -100px;
 53     left: 50%;
 54 }
 55 .control .dis button#again{
 56     display: none;
 57     
 58 }
 59 
 60 .control .dis span {
 61     position: relative;
 62     top: 110px;
 63     display: inline-block;
 64     font-weight: 600;   
 65     padding: 5px 10px;
 66     border-radius: 5px;
 67     
 68 }
 69 .control .dis span.lei{
 70     background: red;
 71     float: left;
 72     margin-left: 30px;
 73 }
 74 .control .dis span.save{
 75     background: greenyellow;
 76     margin-left: 20px;
 77 }
 78 .control .dis span.flag{
 79     background: yellow;
 80     float: right;
 81     margin-right: 30px;
 82     
 83 }
 84 .control .sore {
 85     width: 300px;
 86     float: right;
 87 }
 88 .control .sore .time {
 89     font-size: 40px;
 90     margin-top: 30px;
 91 }
 92 .control .sore .residual {
 93     font-size: 20px;
 94     margin-top: 30px;
 95     margin-left: 20px;
 96 }
 97 
 98 
 99 
100 #mysaolei {
101     /* width: 50%; */
102     /* height: 200px; */
103     position: relative;
104     left: 50%;
105     transform: translateX(-50%);
106     margin-top: 20px;
107     border: 1px solid silver;
108     border-radius: 2px;
109     margin-bottom: 30px;
110 }
111 #mysaolei div {
112     position: absolute;
113     width: 23px;
114     height: 23px;
115     line-height: 23px;
116     font-size: 16px;
117     text-align: center;
118     border: 1px solid silver;
119     border-radius: 2px;
120 }
121 #mysaolei div.lei{
122     background: red;
123 }
124 #mysaolei div.save{
125     background: greenyellow;
126 }
127 #mysaolei div.flag{
128     background: yellow;
129     
130 }
css

重点js!

  1 window.onload = function(){
  2     var col , 
  3         row , 
  4         lei_n , // 雷数
  5         lei_flag = 0, // 类标记数量
  6         mount = 0,
  7         save_num = 0, // 不是雷被点开的数量
  8         setTime,
  9         useTime = 0,
 10         lock = true;
 11         map = [];
 12         
 13     var mysaolei = document.getElementById("mysaolei"), // 存储地图位置信息
 14         begin = document.getElementById("begin"),
 15         again = document.getElementById("again"),
 16         time = document.getElementById("time"),
 17         leave = document.getElementById("leave"),
 18         col_v = document.getElementById("col"),
 19         row_v = document.getElementById("row"),
 20         lei_v = document.getElementById("lei");
 21 
 22     var reg = /^\d+$/;
 23 
 24     col_v.addEventListener('input',function(){       
 25         if(reg.test(col_v.value) ){
 26             if(col_v.value < 1 ){
 27                 col_v.value = 1;
 28             }else if(col_v.value > 40){
 29                 col_v.value = 40;
 30             }
 31         }else{
 32             col_v.value = '';
 33         }
 34     })
 35     row_v.addEventListener('input',function(){       
 36         if(reg.test(row_v.value) ){
 37             if(Number(row_v.value)  < 1 ){
 38                 row_v.value = 1;
 39             }else if(Number(row_v.value) > 30){
 40                 row_v.value = 30;
 41             }
 42         }else{
 43             row_v.value = '';
 44         }
 45     })
 46     lei_v.addEventListener('input',function(){       
 47         if(reg.test(lei_v.value) ){
 48             if(Number(lei_v.value) < 1 ){
 49                 lei_v.value = 1;
 50             }else if(Number(lei_v.value) > 1200){
 51                 lei_v.value = 1200;
 52             }
 53         }else{
 54             lei_v.value = '';
 55         }
 56     })
 57     begin.onclick = function(){
 58         col =  col_v.value || 10;
 59         row =  row_v.value || 10;
 60         lei_n =  lei_v.value || 10;
 61         if((col * row) < lei_n){
 62             alert("你TM要这么多雷炸死谁! 格子都放不下了!赶紧少放点雷!");
 63             return false;            
 64         }
 65         this.style.display = "none";
 66         again.style.display = "block";
 67         init();
 68         
 69     }
 70     again.onclick = function(){
 71         col =  col_v.value || 10;
 72         row =  row_v.value || 10;
 73         lei_n =  lei_v.value || 10;
 74         if((col * row) < lei_n){
 75             alert("你TM要这么多雷炸死谁! 格子都放不下了!赶紧少放点雷!");
 76             return false;            
 77         }
 78         map = [];
 79         lei_flag = 0;
 80         save_num = 0;
 81         mount = 0;
 82         useTime = 0;
 83         clearInterval(setTime);
 84         mysaolei.innerHTML = '';        
 85         init();
 86     }
 87     
 88 
 89 
 90 
 91 
 92 
 93 
 94 
 95 
 96     function createMap(){ // 创建地图数组
 97         for(var i = 0; i < row; i ++){
 98             map[i] = [];
 99             for(var j = 0; j < col; j ++){
100                 map[i][j] = {'x' : i ,'y' : j , 'num' : 0 , 'flag' : false , 'lei': false}
101             }
102         }
103         createLei();  
104         computeNum();   
105     }
106 
107     function createLei(){
108         lei_map = 0; // 雷以创建个数
109         for(;;){
110             var randomX = parseInt(Math.random() * row);
111             var randomy = parseInt(Math.random() * col);
112             if(lei_map == lei_n){
113                 return
114             }else if(!map[randomX][randomy].lei){
115                 map[randomX][randomy].lei = true;
116                 lei_map ++;
117             }
118         }
119     }
120 
121     function computeNum(){ // 数组负值
122         for(var i = 0; i < row; i ++){            
123             for(var j = 0; j < col; j ++){                
124                 if(map[i][j].lei){                
125                     if(map[i-1] && map[i-1][j-1] && !map[i-1][j-1].lei){map[i-1][j-1].num ++};
126                     if(map[i-1] && map[i-1][j]   && !map[i-1][j].lei  ){map[i-1][j].num ++};
127                     if(map[i-1] && map[i-1][j+1] && !map[i-1][j+1].lei){map[i-1][j+1].num ++};
128                     if(map[i]   && map[i][j-1]   && !map[i][j-1].lei  ){map[i][j-1].num ++};
129                     if(map[i]   && map[i][j+1]   && !map[i][j+1].lei  ){map[i][j+1].num ++};
130                     if(map[i+1] && map[i+1][j-1] && !map[i+1][j-1].lei){map[i+1][j-1].num ++};
131                     if(map[i+1] && map[i+1][j]   && !map[i+1][j].lei  ){map[i+1][j].num ++};
132                     if(map[i+1] && map[i+1][j+1] && !map[i+1][j+1].lei){map[i+1][j+1].num ++};
133                 }
134             }
135         }
136     }
137 
138     function mapInBox(){ // 地图展示
139         mysaolei.style.width = col * 27 + 2 + 'px';
140         mysaolei.style.height = row * 27 + 2 + 'px';         
141         mysaolei.oncontextmenu = function(){return false}; // 禁止右键菜单事件
142         for(var i = 0; i < row; i ++){
143             for(var j = 0; j < col; j ++){
144                 var temp =  createSquare(map[i][j]);
145                 mysaolei.appendChild(temp);
146             }
147         }
148     }
149 
150     function createSquare(obj){ // 创建单元格 
151         var square = document.createElement('div');
152         square.style.top = obj.x * 25 + (obj.x + 1) * 2 + 'px';
153         square.style.left = obj.y * 25 + (obj.y + 1) * 2 + 'px';
154         square.num = obj.num;
155         square.flag = obj.flag;
156         square.lei = obj.lei;
157         square.index = [obj.x, obj.y];
158         square.eq = obj.x * row + obj.y;
159         square.addEventListener('mousedown',click);
160         return square;
161     }
162 
163     function click(event){ // 点击事件
164         if(!lock){return false}
165         var e = event || window.event; 
166         if(e.which == 1){
167             leftClick(this);
168         }
169         if(e.which == 3) {
170             rightClick(this)
171         }
172     }
173     function leftClick(self){ // 左键事件
174         if(!self.className){
175             if(self.lei){
176                 self.classList.add("lei");
177                 gameOver();
178             }else{
179                 // console.log(self.eq);
180                 var x = self.index[0];
181                 var y = self.index[1];
182                 self.classList.add("save");
183                 save_num ++ ;
184                 if(self.num !=0 ){                    
185                     self.innerHTML = self.num;
186                 }else if (self.num == 0){
187                     for( var i = x - 1 ; i < x + 2; i ++){
188                         for(var j = y - 1; j < y + 2;j ++){
189                             var arr = [i,j];
190                             if(mysaolei.children[i*col + j] && (mysaolei.children[i*col + j].index[0] == arr[0] && mysaolei.children[i*col + j].index[1] == arr[1])){
191                                 leftClick(mysaolei.children[i*col + j]);
192                             }
193                         }
194                     }
195                 }
196                 isGameWin();
197             }
198         }
199     }
200     function rightClick(self){ // 右键事件
201         if(self.classList.contains("flag") || !self.className){
202             self.classList.toggle("flag");
203             self.flag = !self.flag;
204             lei_flag = self.flag ? lei_flag + 1 : lei_flag - 1;
205             if(lei_n == lei_flag){ 
206                 for(var i = 0; i < mysaolei.children.length; i++){
207                     if ((mysaolei.children[i].flag + mysaolei.children[i].lei) == 2){
208                         mount += 1;
209                     }
210                 }
211                 if(mount != lei_n){
212                     mount = 0
213                 }
214             }
215         }
216         showLeaveLei();
217         isGameWin();
218     }
219 
220     function gameOver(){ // 游戏结束事件
221         for(var i = 0; i < mysaolei.children.length; i++){
222             if(mysaolei.children[i].lei){
223                 mysaolei.children[i].classList.add("lei");
224             }            
225         }
226         lock = false;
227         clearInterval(setTime);
228         setTimeout(function(){
229             alert("game over !!!");
230         },500)
231     }
232     function isGameWin(){
233         if(mount == lei_n || save_num == (row * col - lei_n)){
234             lock = false;
235             clearInterval(setTime);
236             alert('大吉大利!今晚吃鸡!');
237             map = [];
238             lei_flag = 0;
239             save_num = 0;
240             mount = 0;
241         }
242     }
243     function showLeaveLei(){
244         leave.innerHTML = lei_n - lei_flag + '个';
245     }
246     function init(){
247         lock = true;
248         createMap();           
249         // console.log(map);        
250         mapInBox();
251         showLeaveLei();
252         setTime = setInterval(function(){
253             useTime += 0.5;
254             time.innerHTML = parseInt(useTime) + 's';
255         },500)
256     }  
257 }
JavaScript

纯手打!独立完成,欢迎提意见,找bug!

 

posted @ 2018-10-12 09:10  不爱吃鱼的喵~  阅读(646)  评论(0编辑  收藏  举报