很久以前写的 当时都没写注释的 刚加上了 (尼玛,好多自己都不认识了 ... )
不足的地方就是本来想写个游戏排名的统计的,等有空了再加上(好像每次都这么说 然后就等好久好久...)
还有就是没有实现:点击第一个格子不能是雷的功能
<style>ul{padding:0;list-style:none;}#mine{overflow:hidden;width:30px;height:30px;border:1px solid #966;}#mine li{float:left;width:30px;height:30px;line-height:30px;text-align:center;font-size:14px;color:#222;}#mine .mine_01{background:url(mine.gif) no-repeat;}#mine .mine_02{background:url(mine.gif) -30px 0 no-repeat;}#mine .mine_03{background:url(mine.gif) -60px 0 no-repeat;}#mine .mine_04{background:url(mine.gif) -90px 0 no-repeat;}#mine .mine_05{background:url(mine.gif) -120px 0 no-repeat;}#mine .mine_06{background:url(mine.gif) -150px 0 no-repeat;}#mine .mine_07{background:url(mine.gif) -180px 0 no-repeat;}#count{font-size:12px;}#time{color:#900;font-weight:bold;}</style> <select id="wh"> <option value="8*10">8*10</option> <option value="10*10">10*10</option> <option value="12*12">12*12</option> </select> <button id="ready">重新开始</button><div id="count"> 计时: <span id="time">0</span></div><ul id="mine"></ul>ie6+ ff oprea 谷歌opera 早期版本 默认不支持document.oncontextmenu事件 没有找到好的替代方法<script>var $ = function(id){return document.getElementById(id)};window.onload=function ready(){var V=$("wh").value.split("*")setMineField(Number(V[0]),Number(V[1]));$("wh").onchange=$("ready").onclick=function(){V=$("wh").value.split("*")setMineField(Number(V[0]),Number(V[1]))}}//---------------------------------------------------雷区var mineField={_mineW:30, //每一个雷的宽度 必须和样式同步_mineH:30,_mineFieldBlock:$("mine"),_mineFieldEle:$("mine").getElementsByTagName("li"),_time:$("time"),status:0, //雷区状态 0还没开始 1开始了 已经在计时了 2游戏结束了mineNum:0, //雷数clearPlace:0, //统计扫除的格子;x:0,//列y:0,//行density:0.2,//雷的密度 雷区密度不宜超过0.5 在有些尺寸的雷区下 过高的设置 无法生成mineMap数组mineMap:[],//雷区的二维图,0 : 不是雷-1 : 雷time:-1,//计时 sdebug:false //调试模式}//mineField object endfunction timedCount(){if(mineField.status!=1){return false}mineField.time++;mineField._time.innerHTML=mineField.time;setTimeout("timedCount()",1000);}//--------------------------------------对雷的状态设置function setThisMine(str,index){var allMine=mineField._mineFieldEle;//设置雷是否插旗if(str=="setOn"){var thisMine=allMine[index];thisMine.on=thisMine.on<2?thisMine.on+1:0;if(thisMine.on==1){thisMine.className="mine_03";}//插旗else if(thisMine.on==2){thisMine.className="mine_04"}//取消插旗else if(thisMine.on==0){thisMine.className="mine_01"}//取消插旗return false;}//显示方格if(str=="show"){if(Object.prototype.toString.call(index) === "[object Array]"){//显示一大片mineField.clearPlace=mineField.clearPlace+index.length;for(var i=0;i<index.length;i++){var thisMine=allMine[index[i]];thisMine.innerHTML=mineField.mineMap[thisMine.index];thisMine.className="mine_02";thisMine.on=3;}}else{//显示单个非雷区域mineField.clearPlace++;allMine[index].on=3;allMine[index].innerHTML=mineField.mineMap[index];allMine[index].className="mine_02";}if(mineField.clearPlace==mineField.x*mineField.y-mineField.mineNum){//恭喜你alert("恭喜你");for(var i=0;i<allMine.length;i++){if(mineField.mineMap[allMine[i].index]==-1){allMine[i].className="mine_07";}}mineField.status=2;return false;}}//显示全部雷if(str=="peng"){for(var i=0;i<allMine.length;i++){if(mineField.mineMap[allMine[i].index]==-1){allMine[i].className=i==index?"mine_06":"mine_05";}}mineField.status=2;}}//-----------------------------------------------设置行数 和 列数function setMineField(a,b){var thisMineFiele=mineField._mineFieldBlock;DivBox=document.createElement("div"),num=a*b,k=0;thisMineFiele.innerHTML="";//雷区参数调整mineField.x=a;//有几列mineField.y=b;//有几行mineField.mineNum=Math.floor(a*b*mineField.density);mineField.status=0;mineField.time=-1;mineField.clearPlace=0;mineField.mineMap.length=0;mineField._time.innerHTML=0;//生成雷区地图setMineMap();//生成雷区(创建li)while(k<num){var newLi=document.createElement("li");if(mineField.debug) newLi.innerHTML=mineField.mineMap[k];//作弊newLi.className="mine_01";DivBox.appendChild(newLi);k++;}thisMineFiele.style.height=mineField._mineW*b+"px";thisMineFiele.style.width=mineField._mineH*a+"px";thisMineFiele.innerHTML=DivBox.innerHTML;DivBox=null;setEvent();//事件}//-----------------------------------生成雷区地图function setMineMap(){var num=mineField.x*mineField.y,mineNum=mineField.mineNum,Interval=Math.floor(num/mineNum);for(var i=0;i<num;i++){if(i%Interval==0&&i<mineNum*Interval){mineField.mineMap[i]=-1;}else{mineField.mineMap[i]=0;}//雷等距离分布与数组中}mineField.mineMap.sort(function(){ return 0.5 - Math.random()})//打乱数组//判断方格周围是否都是雷 如果是的话 要重新生成雷区 从而避免成片雷区的存在var br=0,//所在行x=mineField.x,L_T,T,R_T,L,R,L_B,B,R_B;for(var i=0;i<num;i++){br=Math.ceil((i+1)/x);L_T = i-x-1;T= i-x;R_T = i-x+1;L= i-1;R= i+1;L_B = i+x-1;B= i+x;R_B = i+x+1; //坐上角 如果在雷区 并且是在上一行 并且他不是雷 就进行下一方格检测 if(L_T>=0&&Math.ceil((L_T+1)/x)==br-1&&mineField.mineMap[L_T]==0){continue} if(T >=0&&Math.ceil((T +1)/x)==br-1&&mineField.mineMap[T ]==0){continue} if(R_T>=0&&Math.ceil((R_T+1)/x)==br-1&&mineField.mineMap[R_T]==0){continue}if(L>=0 &&Math.ceil((L+1)/x)==br&&mineField.mineMap[L]==0){continue} if(R<num&&Math.ceil((R+1)/x)==br&&mineField.mineMap[R]==0){continue}if(L_B<num&&Math.ceil((L_B+1)/x)==br+1&&mineField.mineMap[L_B]==0){continue} if(B <num&&Math.ceil((B +1)/x)==br+1&&mineField.mineMap[B ]==0){continue} if(R_B<num&&Math.ceil((R_B+1)/x)==br+1&&mineField.mineMap[R_B]==0){continue}setMineMap(); return false}//统计非雷方格周围的雷数for(i=0;i<num;i++){ if(mineField.mineMap[i]==-1){continue} var thisMineNum=0 br=Math.ceil((i+1)/x); L_T = i-x-1; T= i-x; R_T = i-x+1; L= i-1; R= i+1; L_B = i+x-1; B= i+x; R_B = i+x+1;if(L_T>=0&&Math.ceil((L_T+1)/x)==br-1&&mineField.mineMap[L_T]==-1){thisMineNum++;} if(T >=0&&Math.ceil((T +1)/x)==br-1&&mineField.mineMap[T ]==-1){thisMineNum++;} if(R_T>=0&&Math.ceil((R_T+1)/x)==br-1&&mineField.mineMap[R_T]==-1){thisMineNum++;}if(L>=0 &&Math.ceil((L+1)/x)==br&&mineField.mineMap[L]==-1){thisMineNum++;} if(R<num&&Math.ceil((R+1)/x)==br&&mineField.mineMap[R]==-1){thisMineNum++;}if(L_B<num&&Math.ceil((L_B+1)/x)==br+1&&mineField.mineMap[L_B]==-1){thisMineNum++;} if(B <num&&Math.ceil((B +1)/x)==br+1&&mineField.mineMap[B ]==-1){thisMineNum++;} if(R_B<num&&Math.ceil((R_B+1)/x)==br+1&&mineField.mineMap[R_B]==-1){thisMineNum++;}mineField.mineMap[i]=thisMineNum;}}//----------------------------------雷区事件function setEvent(){var thisMineFiele=mineField._mineFieldBlock,allMine=mineField._mineFieldEle,iMax=mineField.x*mineField.y;for(var i=0;i<iMax;i++){allMine[i].index=i;allMine[i].on=0;//0为默认 1为插旗 2为问号 3为显示}thisMineFiele.onmouseup=function(e){if(mineField.status==2){return false;}if(mineField.status==0){mineField.status=1;timedCount();}var e=e||window.event,thisObj=e.target||e.srcElement;if(thisObj.nodeName=="UL"||thisObj.on==3){return false;}var Btn=getButton(e);if(Btn== 0){//左键if(thisObj.on==1){return false;}//插旗子了 就不能点了if(mineField.mineMap[thisObj.index]==-1){//点雷了setThisMine("peng",thisObj.index);}else if(mineField.mineMap[thisObj.index]==0){//点到空地了 打开一大片//alert("你运气真好")var allShowMine=minesShow(thisObj.index);setThisMine("show",allShowMine)}else{//显示一个格子setThisMine("show",thisObj.index)}}if(Btn== 2){//右键 setThisMine("setOn",thisObj.index);}}}//--------------------------------按到空格时 显示一大片function minesShow(I){var allMine=mineField._mineFieldEle,allShowMine=[I];//保存要显示的雷的下标allMine[I].on=3;see(I);//查询下标为I的周围的方格function see(allI){var _allI=[];if(Object.prototype.toString.call(allI) === "[object Array]"){for(var i=0;i<allI.length;i++){f(allI[i])}}else{f(allI)}function f(thisI){var text,x=mineField.x,br,num=x*mineField.y,L_T,T,R_T,L,R,L_B,B,R_B;text="_"+allShowMine.join("_")+"_";//用来判断下标是否已经写入数组br=Math.ceil((thisI+1)/x);L_T = thisI-x-1;T= thisI-x;R_T = thisI-x+1;L= thisI-1;R= thisI+1;L_B = thisI+x-1;B= thisI+x;R_B = thisI+x+1; //左上角的方格 如果是在雷区 又是在上一行 又是没翻开的格子 又是空格 那么就写如_allI数组 来进行下一次检索 if(L_T>=0&&Math.ceil((L_T+1)/x)==br-1&&allMine[L_T].on==0&&mineField.mineMap[L_T] == 0){_allI.push(L_T);} if(T >=0&&Math.ceil((T +1)/x)==br-1&&allMine[T ].on==0&&mineField.mineMap[T ] == 0){_allI.push(T);} if(R_T>=0&&Math.ceil((R_T+1)/x)==br-1&&allMine[R_T].on==0&&mineField.mineMap[R_T] == 0){_allI.push(R_T);}if(L>=0&&Math.ceil((L+1)/x)==br&&allMine[L].on==0&&mineField.mineMap[L] == 0){_allI.push(L);} if(R<num&&Math.ceil((R+1)/x)==br&&allMine[R].on==0&&mineField.mineMap[R] == 0){_allI.push(R);}if(L_B<num&&Math.ceil((L_B+1)/x)==br+1&&allMine[L_B].on==0&&mineField.mineMap[L_B] == 0){_allI.push(L_B);} if(B <num&&Math.ceil((B +1)/x)==br+1&&allMine[B ].on==0&&mineField.mineMap[B ] == 0){_allI.push(B);} if(R_B<num&&Math.ceil((R_B+1)/x)==br+1&&allMine[R_B].on==0&&mineField.mineMap[R_B] == 0){_allI.push(R_B);} //------------------------------------------------ //左上角的的格子 如果在雷区 又是在上一行 又是没翻开的格子 又是没写入allShowMine数组的 那就写入吧 并提前标记为翻开的格子 if(L_T>=0&&Math.ceil((L_T+1)/x)==br-1&&allMine[L_T].on==0&&text.indexOf("_"+L_T+"_") == -1){allShowMine.push(L_T);allMine[L_T].on=3} if(T >=0&&Math.ceil((T +1)/x)==br-1&&allMine[T ].on==0&&text.indexOf("_"+T+"_") == -1){allShowMine.push(T);allMine[T].on=3} if(R_T>=0&&Math.ceil((R_T+1)/x)==br-1&&allMine[R_T].on==0&&text.indexOf("_"+R_T+"_") == -1){allShowMine.push(R_T);allMine[R_T].on=3}if(L>=0&&Math.ceil((L+1)/x)==br&&allMine[L].on==0&&text.indexOf("_"+L+"_") == -1){allShowMine.push(L);allMine[L].on=3} if(R<num&&Math.ceil((R+1)/x)==br&&allMine[R].on==0&&text.indexOf("_"+R+"_") == -1){allShowMine.push(R);allMine[R].on=3}if(L_B<num&&Math.ceil((L_B+1)/x)==br+1&&allMine[L_B].on==0&&text.indexOf("_"+L_B+"_") == -1){allShowMine.push(L_B);allMine[L_B].on=3} if(B <num&&Math.ceil((B +1)/x)==br+1&&allMine[B ].on==0&&text.indexOf("_"+B+"_") == -1){allShowMine.push(B );allMine[B ].on=3} if(R_B<num&&Math.ceil((R_B+1)/x)==br+1&&allMine[R_B].on==0&&text.indexOf("_"+R_B+"_") == -1){allShowMine.push(R_B);allMine[R_B].on=3}if(_allI.length!=0){see(_allI)}}}return allShowMine}//--------------------------------------document.oncontextmenu=function(){return false;}//禁止右键菜单function getButton(e){var Btn;if(document.implementation.hasFeature("MouseEvents","2.0")){Btn=e.button;}else{switch(e.button){case 0:case 1:case 3:case 5:case 7: Btn=0; break;case 2:case 6: Btn=2; break;case 4: Btn=9; break;}}return Btn;}</script>以上所述就是本文的全部内容了,希望大家能够喜欢。