闲来无事,想用javascrpt做些小游戏,感觉Win7系统中的扫雷游戏比较有意思,故花了一些时间通过b编写原生的javascript代码来实现网页版扫雷游戏。
首先,应该通过HTML+CSS写好网页的静态布局,如下所示:
<div class="wrap">
<div class="head">
<div class="hleft">
<em></em><span>扫雷</span>
</div>
<div class="hright">
<span></span><span></span><span id="close"></span>
</div>
</div>
<div class="main"><!--游戏主体部分-->
<p><span>游戏(G)</span><span>帮助(H)</span></p>
<div class="box">
<div id="con"></div>
<div id="maskBox"></div><!--表面的遮罩层-->
<div id="failBox"><!--游戏结束后的弹出框-->
<div class="fhead">
<span>游戏失败</span>
<span id="fbClose"></span>
</div>
<div class="fbCon">
<h3 id="fbTitle"></h3>
<p id="gtime"></p>
<p><span id="bestTime"></span><span id="gDate"></span></p>
<p><span id="total"></span><span id="winSum"></span></p>
<input type="button" id="playAgain" value="再玩一局" />
</div>
</div>
<div class="foot">
<div class="fleft">
<span class="ficon"></span><span class="fNum" id="ftime">0</span>
</div>
<div class="fright">
<span class="fNum">10</span><span class="ficon"></span>
</div>
</div>
</div>
</div>
</div>
扫雷游戏重点在于javascript部分,故HTML+CSS布局部分就不详细介绍了。
接下来,开始写javascript代码:
(1)先要完成页面初始化,生成页面主体部分的方格及表面遮罩层方格,如下图所示:
(2)然后再方格中,随机选择10个位置买下10个雷;
(3)埋完雷后,需要计算每个方格的周围8个方格内的雷数并写入方格中,如下图所示:
相关的详细代码如下:
function init(){
var lei=0;
//生成游戏界面的9*9方格及遮罩层
var con=document.getElementById("con");
var maskBox=document.getElementById("maskBox");
var conih="";
var mbih="";
for(var i=0;i<9;i++){
for(var j=0;j<9;j++){
conih+="<span></span>";
mbih+="<em></em>";
}
}
con.innerHTML=conih;
maskBox.innerHTML=mbih;
//埋雷
var csps=con.getElementsByTagName("span");
for(var i=0;i<10;i++){
lei=Math.floor(Math.random()*csps.length);
if(csps[lei].className==""){
csps[lei].className="cLei";
}else{
i--;
}
}
//计算每个方格周围存在的雷数
for(var i=0;i<csps.length;i++){
csps[i].onOff=true;
if(csps[i].className=="cLei"){
continue;
}
num=0;
if(i%9!=8){
if(i+10<csps.length && csps[i+10].className == "cLei"){
num+=1;
}
if(i+1<csps.length && csps[i+1].className=="cLei"){
num+=1;
}
if(i-8>=0 && csps[i-8].className=="cLei"){
num+=1;
}
}
if(i%9!=0){
if(i-1>=0 && csps[i-1].className=="cLei"){
num+=1;
}
if(i-10>=0 && csps[i-10].className=="cLei"){
num+=1;
}
if(i+8<csps.length && csps[i+8].className=="cLei"){
num+=1;
}
}
if(i-9>=0 && csps[i-9].className=="cLei"){
num+=1;
}
if(i+9<csps.length && csps[i+9].className=="cLei"){
num+=1;
}
if(num!=0){
csps[i].innerHTML=num;
}
}
}
(4)
为每个方格绑定点击事件处理函数,该函数要实现的功能是:点击的这个方格下面是否是雷及各自情况下如何处理:
a.如果点击的方格下面不是雷,而是数字。则只需此方格表面遮罩层,露出底下的数字即可;
b.如果点击的方格下面不是雷,并且没有数字,而是空白。则需要以此方格为中心,找出周围内容是空白的方格并去除这些方格的表面遮罩层。这一步算是整个游戏的难点了,本人是利用递归来一层一层找出所有内容为空白的方格的;实现效果如下图所示:
当点击上图中的红色圈出来的那块方格时,出现的效果是:以这个方格为中心,向四处发散,露出空白方格。
详细代码如下:
function fn(n){
var csps=con.getElementsByTagName("span");
if(csps[n].className=="cLei"){
return;
}
mbems[n].style.opacity=0;
if(csps[n].innerHTML=="" && csps[n].onOff){
csps[n].onOff=false;
if(n+9<csps.length && csps[n+9].className=="" &&csps[n+9].onOff){
mbems[n+9].style.opacity=0;
if(csps[n+9].innerHTML==""){
fn(n+9);
}
}
if(n%9!=0){
if(n-1>=0 && csps[n-1].className=="" && csps[n-1].onOff){
mbems[n-1].style.opacity=0;
if(csps[n-1].innerHTML==""){
fn(n-1);
}
}
if(n-10>=0 && csps[n-10].className=="" && csps[n-10].onOff){
mbems[n-10].style.opacity=0;
if(csps[n-10].innerHTML==""){
fn(n-10);
}
}
if(n+8<csps.length && csps[n+8].className=="" && csps[n+8].onOff){
mbems[n+8].style.opacity=0;
if(csps[n+8].innerHTML==""){
fn(n+8);
}
}
}
if(n%9!=8){
if(n+10<csps.length && csps[n+10].className=="" && csps[n+10].onOff){
mbems[n+10].style.opacity=0;
if(csps[n+10].innerHTML==""){
fn(n+10);
}
}
if(n+1<csps.length && csps[n+1].className=="" && csps[n+1].onOff){
mbems[n+1].style.opacity=0;
if(csps[n+1].innerHTML==""){
fn(n+1);
}
}
if(n-8>=0 && csps[n-8].className=="" && csps[n-8].onOff){
mbems[n-8].style.opacity=0;
if(csps[n-8].innerHTML==""){
fn(n-8);
}
}
}
if(n-9>=0 && csps[n-9].className=="" && csps[n-9].onOff){
mbems[n-9].style.opacity=0;
if(csps[n-9].innerHTML==""){
fn(n-9);
}
}
}
}
c.
如果点击的方格是雷,则这个游戏就结束了,如下图所示:
总结:
总体来说,扫雷游戏实现难度不大。本人在做的时候,基本只在用递归实现时遇到困难,浏览器报了堆栈溢出的错误。然后经过调试查找错误,发现是因为函数在递归时,有的空白方格在找出后,又会重复被找到,这样就会一直递归下去,程序跳不出来,然后就会报错。找到报错的原因就好办了,稍加修改代码,为每个方格加一个是否被点开的开关,那么空白方格一旦被找出,就立刻修改这个开关的状态,并且查找空白方格的判断条件再补充判断方格的开关状态就行了。再进行测试,发现bug得以解决。
另外,在这里只贴出一些关键代码,如果需要详细源码可以留邮箱。