用javascript实现win7系统扫雷游戏

闲来无事,想用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得以解决。

另外,在这里只贴出一些关键代码,如果需要详细源码可以留邮箱。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值