原作者来自JAVAEYE,原程序缺少右键标记。我对程序做了稍许修改,并增加了十分简单的计时、积分和称号,感谢原作者得辛勤工作。 先上图 代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gbk"> <title>Untitled Document</title> <mce:script type="text/javascript"><!-- var bgObj; function showWin(strInfo){ var sWidth,sHeight; sWidth=screen.width; sHeight=screen.height; bgObj=document.createElement("div"); bgObj.setAttribute( "id", "bgDiv"); bgObj.style.position="absolute"; bgObj.style.top="0"; bgObj.style.background="#cccccc"; bgObj.style.filter="progid:DXImageTransform.Microsoft.Alpha(style=3,opacity=25,finishOpacity=75)"; bgObj.style.opacity="0.6"; bgObj.style.left="0"; bgObj.style.width=screen.width+"px"; bgObj.style.height=screen.height+"px"; document.body.appendChild(bgObj); //main.style.display='block'; main.style.visibility = "visible"; main.style.zIndex = "50"; main.style.width="100%"; document.getElementById("warnInfo").innerHTML="<h2>"+strInfo+"</h2>"; } function closeWin(){ clearTimeout(time); init(); document.body.removeChild(bgObj); main.style.visibility = "hidden"; } // --></mce:script> <mce:style type="text/css"><!-- /*初始状态*/ .f0{background-color:#425ccd} /*鼠标悬停状态*/ .f1{background-color:#609aff} /*扫雷状态*/ .f2{background-color:#cbd8ea} /*地雷状态*/ .f3{background-color:#cbd8ea;background-image:url("mine2.png")} /*扫出的地雷*/ .f4{background-color:#cbd8ea;background-image:url("mine.png")} .f5{background-color:#cbd8ea;background-image:url("mark.jpg")} td {width:18px;} tr {height:18px;} font{font-weight:bolder;} .n1{color:#4050be} .n2{color:#1e6902} .n3{color:#b05964} .n4{color:#010184} .n5{color:#8c2d34} .n6{color:#ff0080} .n7{color:#ff8000} .n8{color:#00ffff} #main{position:absolute;z-index:50; visibility:hidden} --></mce:style><style type="text/css" mce_bogus="1"> /*初始状态*/ .f0{background-color:#425ccd} /*鼠标悬停状态*/ .f1{background-color:#609aff} /*扫雷状态*/ .f2{background-color:#cbd8ea} /*地雷状态*/ .f3{background-color:#cbd8ea;background-image:url("mine2.png")} /*扫出的地雷*/ .f4{background-color:#cbd8ea;background-image:url("mine.png")} .f5{background-color:#cbd8ea;background-image:url("mark.jpg")} td {width:18px;} tr {height:18px;} font{font-weight:bolder;} .n1{color:#4050be} .n2{color:#1e6902} .n3{color:#b05964} .n4{color:#010184} .n5{color:#8c2d34} .n6{color:#ff0080} .n7{color:#ff8000} .n8{color:#00ffff} #main{position:absolute;z-index:50; visibility:hidden} </style> <mce:script type='text/javascript'><!-- //配置信息 宽度 高度 地雷数量(默认为 9 9 10) var setting = {width:9,height:9,mine:10}; var minePostionArray = []; var mineWarnArray=[]; //警告信息数组,记忆生成 var notMineNum; //非雷区的数量 var realnotMineNum; var score; var timeCount; var time; function $(id){ return document.getElementById(id); } Array.prototype.has= function(num){ //可以优化查询算法 var flag =false; for(var i=0;i<minePostionArray.length;i++){ if(num==minePostionArray[i]){ flag = true; break; } } return flag; } function init(){ setting = {width:9,height:9,mine:10}; minePostionArray = []; mineWarnArray=[]; initSetting(); initMainArea(setting.width,setting.height,setting.mine); initMine(setting.width,setting.height,setting.mine); timeCount=0; timedCount(); } function timedCount() { document.getElementById('calculagraph').value=timeCount timeCount+=1; time=setTimeout("timedCount()",1000); } //初始化配置 function initSetting(){ //获得选中的难度 var level = document.FrmSetting.level; var checkLevel = 0; score=0; for(var i =0 ; i<4 ; i++){ if(level[i].checked==true){ checkLevel = i; break; } } //根据难度配置setting switch(checkLevel){ case 0:setting = {width:9,height:9,mine:10};break; case 1:setting = {width:16,height:16,mine:40}; break; case 2:setting = {width:16,height:30,mine:99}; break; case 3:setting = {width:$('width').value,height:$('height').value,mine:$('mine').value};break; } notMineNum=0; realnotMineNum = setting.width*setting.height-setting.mine; } //初始化扫雷游戏主区域界面 function initMainArea(width,height,mine){ var innerHtml = ["<table cellpadding='0' cellspacing='0' border='1' bordercolor='black'>"]; for(var i=0;i<height;i++){ innerHtml.push("<tr>"); for(var j=0;j<width;j++){ var id= i*width+j; innerHtml.push("<td class='f0' id='"+id+"' onmouseover='mouseover(this);' onmouseout='mouseout(this);' onmouseup='if(event.button == 2) mouserightclick(this); else mouseclick(this);'> </td>"); } innerHtml.push("</tr>"); } innerHtml.push("</table>"); var obj = document.getElementById("MainArea"); obj.innerHTML = innerHtml.join(""); } //初始化地雷 function initMine(width,height,mine){ var basicArray = []; var allBlank = width*height; for(var m=0;m<allBlank;m++){ basicArray[m]=m; mineWarnArray[m]=-1; } for(var n=0;n<mine;n++){ var randomNum = Math.floor(Math.random()*(basicArray.length)); minePostionArray.push(basicArray[randomNum]); basicArray.splice(randomNum,1); } minePostionArray.sort(function(a,b){return a-b}); //alert(basicArray); //alert(minePostionArray); //alert("basicArray="+basicArray+" minePostionArray"+minePostionArray); } function mouseover(obj){ if(obj.className=="f0"){ obj.className="f1"; } } function mouseout(obj){ if(obj.className=="f1"){ obj.className="f0"; } } function mouseclick(obj){ score++; if(obj.className=="f1" || obj.className=="f5"){ var index = obj.id; if(minePostionArray.has(index)){ //该位置有地雷 for(var i = 0 ;i<minePostionArray.length;i++){ $(minePostionArray[i]).className="f4"; } obj.className="f3"; clearTimeout(time); showWin("英勇趟雷了"); }else{ //该位置无雷 obj.className="f2"; showNum(index); } } } function mouserightclick(obj){ obj.className="f5"; } function exploit() { var total=score*timeCount; var title; switch(true) { case total<300 : title="神仙"; break; case total<750 : title="妖人"; break; case total<900 : title="雷神"; break; case total<1750 : title="雷公"; break; case total<3100 : title="雷人"; break; case total<4450 : title="雷克萨斯"; break; case total<5850 : title="雷蒙"; break; case total<7000 : title="蕾丝"; break; case total<9600 : title="雷击"; break; case total<10000 : title="天谴"; break; case total<12000 : title="天道"; break; case total<15000 : title="天理难容"; break; case total<20400 : title="人神共愤"; break; case total<31600 : title="天网恢恢"; break; case total<43800 : title="天行健"; break; case total<55200 : title="天人"; break; default : title="打酱油的"; break; } return title+" 积分是:"+(Math.ceil(1000*setting.width*setting.height/total)); } function showNum(index){ notMineNum++; mineWarnArray[index]=-2; var x = index%setting.width; var y = Math.floor(index/setting.width); //alert("index="+index+" "+x+" "+y); var count = 0 ; point1:for(var i = x-1 ; i<=x+1 ; i++){ for(var j= y-1 ; j<=y+1 ;j++){ if(i<0){ continue point1; } if(i>setting.width-1){ break point1; } if(0 <= j && j <= setting.height-1){ var postion = j*setting.width+i; //alert("postion="+postion+" i="+i+" j="+j); if (mineWarnArray[postion] == -1) { if (minePostionArray.has(postion)) { count++; }else{ mineWarnArray[postion] =-2; } } } } } $(index).innerHTML = (count==0)?" ":"<font class='n"+count+"'>"+count+"</font>"; $(index).className="f2"; mineWarnArray[index] = count; if(notMineNum==realnotMineNum){ for(var i = 0 ;i<minePostionArray.length;i++){ $(minePostionArray[i]).className="f4"; } showWin("恭喜您扫雷成功,您的称号是:"+exploit()+"!"); } if(count == 0){ point2:for (var i = x - 1; i <= x + 1; i++) { for (var j = y - 1; j <= y + 1; j++) { if(i<0){ continue point2; } if(i>setting.width-1){ break point2; } if (0 <= j && j <= setting.height-1) { var num =j*setting.width+i; //alert("num"+num); if(mineWarnArray[num]<0){ showNum(num); } } } } /* index = index-0; if(x>0){ if(mineWarnArray[index-1]<0){ showNum(index-1); } } if(x<setting.width-1){ if(mineWarnArray[index+1]<0){ showNum(index+1); } } if(y>0){ if(mineWarnArray[index-setting.width]<0){ showNum(index-setting.width); } } if(y<setting.height-1){ if(mineWarnArray[index+setting.width]<0){ showNum(index+setting.width); } } if (x > 0 && y > 0) { if (mineWarnArray[index - setting.width - 1] < 0) { countRound(index - setting.width - 1); } } if(x > 0 && y<setting.height-1){ if(mineWarnArray[index-setting.width+1]<0){ countRound(index-setting.width+1); } } if(x<setting.width-1 && y>0 ) { if(mineWarnArray[index+setting.width-1]<0){ countRound(index+setting.width-1); } } if(x<setting.width-1 && y<setting.height-1){ if(mineWarnArray[index+setting.width+1]<0){ countRound(index+setting.width+1); } } */ } } // --></mce:script> </head> <body bgcolor="#e8e8e8" oncontextmenu = "return false" > <form name="FrmSetting"> <font size="4">难度</font> <div> <input type="radio" name="level" value="0" checked="checked"><b>初级</b>(10个雷,9*9平铺网格)<br/> <input type="radio" name="level" value="1"><b>中级</b>(40个雷,16*16平铺网格)<br/> <input type="radio" name="level" value="2"><b>高级</b>(99个雷,16*30平铺网格)<br/> <input type="radio" name="level" value="3"><b>自定义</b> 高度(9-24)(H)<input type="text" id="height" value="9" size="2"> 宽度(9-30)(W)<input type="text" id="width" value="9" size="2"> 雷数(10-668)(M)<input type="text" id="mine" value="10" size="3"> </div> <b> 计时:</b><input type="text" id="calculagraph" readonly size="4"><br/> <input type="button" value="开始游戏" onclick="init();"> </form> <div id="main" align="center"> <span id="warnInfo"></span> <input type="button" value="再玩一盘" onclick="closeWin();"/> </div> <div align="center" id="MainArea"></div> </body> </html> <!-- 逻辑层 -- 有雷 无雷 表示层-- 初始状态(0) 点击状态 (1) 扫雷状态(2) 引爆状态(3) 雷的全部数量 --> 涉及到的图片: 核心部分就是showNum和Array.prototype.has ,里面包含了点击展开的递归算法和判断雷位置的算法。