之前看了别人用js做的一个扫雷游戏,但是发现有一堆bug,还不能配置!!
想了一下,自己也做了一个原生js的扫雷游戏,目前还没发现bug,欢迎指出!
游戏主体稍微复杂点的就是递归做扩散(也还好)!
设置了可配置的棋牌和雷数量,并对对输入进行验证!
HTML 没啥好看的!
1 2 3 4 5 6 7Document 8 9 10 11 121336 37 38142415 行数: 161718 列数: 192021 地雷: 222325 26 27 安全区28 地雷29 地雷标记30313235TIME:33剩余地雷:34
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 }
重点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 return114 }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 = 0213 }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 }
纯手打!独立完成,欢迎提意见,找bug!