扫雷游戏-原生js

这篇博客介绍了作者在学习JavaScript基础后,通过观看教学视频制作的一款原生JS扫雷游戏。博客内容包括HTML布局、CSS样式和JS逻辑代码,并展示了游戏的不同状态,如初级、中级以及游戏失败的情况。
摘要由CSDN通过智能技术生成

 

HTML代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<link rel="stylesheet" href="css/index.css" />
	</head>
	<body>
		<div id="mine">
			<div class="level">
				<button >初级</button>
				<button>中级</button>
				<button>高级</button>
				<button>重新开始</button>
			</div>
			<div class="gameBox"></div>
			<div class="info">剩余雷数:<span class="mineNum"></span></div>
		</div>
		<script src="js/index.js" ></script>
	</body>
</html>

CSS代码:

#mine{
	margin: 20px auto;
}
.level{
	text-align: center;
}
.level button{
	/*padding: 5px,15px;*/
	background: #02a4ad;
	color: white;
	/*按钮圆角设计*/
	border-radius:30px;
	outline: none;
	/*更改光标默认箭头样式,改为小手*/
	cursor: pointer;
	margin-bottom: 10px;
}
.level button:active{
	background: #00abff;
}
.info{
	margin-top: 20px;
	text-align: center;
}
table{
	border-spacing:1px ;
	background-color: #929196;
	margin: 0 auto;
}
td{
	padding: 0;
	width: 15px;
	height: 15px;
	background: #ccc;
	/*设置单元格样式*/
	border: 2px solid;
	border-color:  #929196 #ccc #ccc #929196  ;
	/*字体居中并加粗显示*/
	text-align: center;
	line-height:15px ;
	font-weight: bold;
}
.mine{
	background: #d9d9d9 url(../img/雷.jpg) no-repeat center;
	background-size:cover ;
}
.flag{
	background:#ccc url(../img/旗.jpg) no-repeat center;
	background-size:cover ;
}
td.zero{
	border-color:#d9d9d9 ;
	background: #d9d9d9;
}
td.one{
	border-color:#d9d9d9 ;
	background: #d9d9d9;
	color: #00ABFF;
}
td.two{
	border-color:#d9d9d9 ;
	background: #d9d9d9;
	color:green;
}
td.three{
	border-color:#d9d9d9 ;
	background: #d9d9d9;
	color:red;
}
td.four{
	border-color:#d9d9d9 ;
	background: #d9d9d9;
	color:#93208f;
}
td.five{
	border-color:#d9d9d9 ;
	background: #d9d9d9;
	color:#ff7f29;
}
td.six{
	border-color:#d9d9d9 ;
	background: #d9d9d9;
	color:#ff3fff;
}
td.seven{
	border-color:#d9d9d9 ;
	background: #d9d9d9;
	color:#3fffbf;
}
td.five{
	border-color:#d9d9d9 ;
	background: #d9d9d9;
	color:#22ee0f;
}

JS代码:

function Mine(tr,td,mineNum){
	this.tr=tr;//行数
	this.td=td;//列数
	this.mineNum=mineNum;//雷的数量
	
	this.squares=[];//存储所有方块信息,他是一个二维数组,按行列顺序排放
	this.tds=[];//存储所有单元格的DOM(二维数组)
	this.surplusMine=mineNum;//剩余雷的数量
	this.allRight=false;//右击标的小红旗是否全都是雷,用来判断用户是否成功
	
	this.parent = document.querySelector(".gameBox");
	
}
//生成随机数
Mine.prototype.randomNum=function(){
	var square = new Array(this.tr*this.td);//生成一个空数组,数组长度为单元格个数
	for(var i =0;i<square.length;i++){
		square[i]=Math.round(Math.random()*(square.length));
	}
/*	square.sort(function(){return 0.5-Math.random()});*/
	return square.slice(1,this.mineNum);
};
//根据随机数存储数字或雷
Mine.prototype.init=function(){
	var rn=this.randomNum();//雷在格子里的位置
	var n=0;//用来找到格子对应的索引
	for(var i=0;i<this.tr;i++){
		this.squares[i]=[];
		for(var j=0;j<this.td;j++){
			n++;
			/*this.squares[i][j]=;*/
			//取一个方块在数组里的数据要使用行列方式去取,找方块周围的方块是用坐标的方式,坐标与行列方式的x、y正相反
			
			if(rn.indexOf(n)!=-1){
				//如果这个条件成立,说明这个索引对应的是个雷
				this.squares[i][j]={type:'mine',x:j,y:i};
			}else{
				this.squares[i][j]={type:'number',x:j,y:i,value:0};
			}
			
		}
	}
	//取消右击的默认样式
	this.parent.oncontextmenu=function(){
			return false;
	}		
//	console.log(this.squares);
	this.updateNum();
	this.createDom();
	//剩余雷数
	this.mineNum=document.querySelector(".mineNum");
	this.mineNum.innerHTML=this.surplusMine;
};

//创建表格
Mine.prototype.createDom=function(){
	var This=this;
	var table=document.createElement("table");
	for(var i=0;i<this.tr;i++){//行
		var domTr=document.createElement("tr");
		this.tds[i]=[];
		for(var j=0;j<this.td;j++){//列
			var domTd=document.createElement("td");
			
			domTd.pos=[i,j];//把格子的行与列存起来,以便通过这个值去数组中去对应的数据
			domTd.onmousedown=function(){
				This.play(event,this);//This代表的是实例对象,this代表的是实例对象
			};
			//domTd.innerText=1;
			this.tds[i][j]=domTd;
			
			/*if(this.squares[i][j].type=='mine'){
				domTd.className="mine";
			}
			if(this.squares[i][j].type=='number'){
				domTd.innerHTML=this.squares[i][j].value;
			}*/
			
			domTr.appendChild(domTd);
			
			}
		table.appendChild(domTr);
	}
	this.parent.innerHTML="";//避免多次创建
	this.parent.appendChild(table);
};
//寻找一个方格周围的八个方格
Mine.prototype.getAround=function(square){
	var x=square.x;
	var y=square.y;
	var result=[];//把找到的格子的坐标返回
	/*x-1,y-1         x,y-1         x+1,y-1
	 *x-1,y           x,y           x+1,y
	 *x-1,y+1         x,y+1         x+1,y+1
	 * 
	 * */
	//通过坐标去循环九宫格
	for(var i=x-1;i<=x+1;i++){
		for(var j=y-1;j<=y+1;j++){
			if( i<0 || //格子超出了左边的范围
				j<0 || //格子超出了上边的范围
				i>this.td-1 || //格子超出了右边的范围
				j>this.tr-1 || //格子超出了下边的范围
				(i==x&&j==y) || //当前格子是自己
				this.squares[j][i].type=='mine'){//周围格子是个雷
				continue;
			}
				result.push([j,i]);//以行列的方式返回出去
		}
	}
	return result;
}

//更新所有的数字
Mine.prototype.updateNum=function(){
	for(var i=0;i<this.tr;i++){
		for(var j=0;j<this.td;j++){
			//要更新的是雷周围的数字
			if(this.squares[i][j].type=='number'){
				continue;
			}
			//获取到每个雷周围的数字
			var num=this.getAround(this.squares[i][j]);
			for(var k=0;k<num.length;k++){
			/*	num[i]==[0][1];*/
				this.squares[num[k][0]][num[k][1]].value +=1;
			}
		}
	}
	console.log(this.squares);
};

//玩游戏
Mine.prototype.play=function(event,obj){
	var This = this;
	if(event.which==1 && obj.className!='flag'){//后面的条件是,表完小红旗后不能左键点击
		//点击的是左键
		var curSquare=this.squares[obj.pos[0]][obj.pos[1]];
		var cl=['zero','one','two','three','four','five','six','seven','eight'];
		
		
		/*console.log(curSquare);*/
		if(curSquare.type=='number'){
			//用户点到数字//点到非0
			obj.innerHTML=curSquare.value;
			obj.className=cl[curSquare.value];
			//点到0
			if(curSquare.value==0){
				obj.innerHTML='';//数字为0不显示
				//以找到的0周围8个格子找0, 再根据周围0再找周围0,如果没有则不需要再找
				function getAllZero(square){
					var around=This.getAround(square);
					for(var i =0;i<around.length;i++){
						var x=around[i][0];//行
						var y=around[i][1];//列
						
						This.tds[x][y].className=cl[curSquare.value];
						//如果点击某个格子为0 ,则递归继续寻找
						if(This.squares[x][y].value==0){
							//递归为0的位置继续寻找
							if(!This.tds[x][y].check){
								//给对应的td添加一个属性,这条属性用于记录此格子是否被找到过
								//如果找到过则为ture,下一次不会寻找
								This.tds[x][y].check=true;
								getAllZero(This.squares[x][y]);
							}
							
						}else{
							//如果周围不是0,则把数字显示出来
							This.tds[x][y].innerHTML=This.squares[x][y].value;
							This.tds[x][y].className=cl[This.squares[x][y].value]
						}
					}
					
					
				};
				getAllZero(curSquare);
			}

		}else{
			//用户点到雷
			
			this.gameOver(obj);
		}
	}
	
	//点击的是右键
	if(event.which==3){
		//如果右击的是数字,则点击无效
		if(obj.className && obj.className!='flag'){
			return;
		}
		obj.className=obj.className=='flag'?'':'flag';//切换class
		
		if(this.squares[obj.pos[0]][obj.pos[1]].type=='mine'){
			this.allRight==true;
		}else{
		this.allRight==false;
		}
		
		//剩余雷数量的数字变化
		if(obj.className=='flag'){
			this.mineNum.innerHTML=--this.surplusMine;
		}else{
			this.mineNum.innerHTML=++this.surplusMine;
		}
		
		//剩余雷数量为0时,表示用户已表完小红旗,要判断游戏成功还是结束
		if(this.surplusMine==0){
			if(this.allRight){
				//表示游戏成功
				alert("游戏成功");	
			}else{
				alert("游戏失败");
				this.gameOveer();
			}
		}
	}
	
};
//游戏失败
Mine.prototype.gameOver=function(clickTd){
	//1显示所有雷
	//2取消所有格子响应事件
	//3给点击雷设置特殊样式
	for(var i= 0 ;i<this.tr;i++){
		for(var j= 0;j<this.td;j++){
			if(this.squares[i][j].type=='mine'){
				this.tds[i][j].className="mine";
			}
			this.tds[i][j].onmousedown=null;
		}
	}
	if(clickTd){
		clickTd.style.backgroundColor='yellow';
	}
}
//button功能
var btns=document.getElementsByTagName("button");
var mine=null;
var arr=[[9,9,10],[16,16,40],[28,28,99]];
for(let i=0;i<btns.length-1;i++){
	btns[i].onclick=function(){
		mine = new Mine(...arr[i]);//es6
		mine.init();
	}
}
btns[0].onclick();//默认初级

//设置重新开始按钮
btns[3].onclick=function(){
	mine.init();
}

结果图:

打开网页,显示初级状态

中级,点到雷游戏结束

如果小红旗标完,但下面有雷,则游戏失败

 

这是我刚学完js基础之后,看了老师教学视频一起写了这个原生js的一个扫雷小游戏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值