说明:主要是做做玩玩的,先把主要功能实现。
扫雷主要分为这几块内容:
- 生成一张N x N地图
- 在地图上随机分布地雷
- 点击地图上每个格子事件
- 点击到雷时,Game Over;
- 点记到雷旁边时,显示周围雷的个数;
- 点击到空白时,显示大片安全区域;
页面的基础结构
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="lei">
<ul id="map">
</ul>
</div>
</body>
</html>
这里有部分DOM元素操作,使用jquery库。
雷图片:ball.png,可随便找一张。
生成一张N x N地图
扫雷界面主要通过ul、li来实现。
<ul>
<li></li>
<li></li>
<li></li>
</ul>
NxN的地图,通过两次for循环生成地图数组,默认值为0;
for (var i = 0; i < wi; i++) {
maparr[i] = [];
for (var j = 0; j < he; j++) {
maparr[i][j]=0;
}
}
在地图上随机分布地雷
for (var i = 0; i < bomb; i++) {
var r = getRandomBetween(0,wi);
var c = getRandomBetween(0,he);
maparr[r][c]=-1;
}
获取随机数,设置r行c列处为雷。然后渲染dom元素
setHtmlDom:function(arr) {
var html="";
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
html+='<li class="mli" style="background-color:wheat" ai="'+i+'" aj="'+j+'" val="'+arr[i][j]+'" onclick="game.clkevent('+arr[i][j]+',this)"></li>';
}
}
$("#map").html(html);
},
根据雷的分布,获取每个方格中应填入的数值,显示周围的地雷数。
for (var i = 0; i < maparr.length; i++) {
for (var j = 0; j < maparr[i].length; j++) {
var a = maparr[i][j]
if(a!==-1){
(i-1>=0)&&(j-1>=0)&&(maparr[i-1][j-1]===-1)&&(a+=1);
(i-1>=0)&&(maparr[i-1][j]===-1)&&(a+=1);
(i-1>=0)&&(j+1<=he-1)&&(maparr[i-1][j+1]===-1)&&(a+=1);
(j+1<=he-1)&&(maparr[i][j+1]===-1)&&(a+=1);
(j-1>=0)&&(maparr[i][j-1]===-1)&&(a+=1);
(i+1<=wi-1)&&(j-1>=0)&&(maparr[i+1][j-1]===-1)&&(a+=1);
(i+1<=wi-1)&&(maparr[i+1][j]===-1)&&(a+=1);
(i+1<=wi-1)&&(j+1<=he-1)&&(maparr[i+1][j+1]===-1)&&(a+=1);
maparr[i][j]=a;
}
}
}
return maparr;
点击地图上每个格子事件
html+='<li class="mli" style="background-color:wheat" ai="'+i+'" aj="'+j+'" val="'+arr[i][j]+'" onclick="game.clkevent('+arr[i][j]+',this)"></li>';
点击到雷时,游戏结束
布雷的方格处,arr[i][j]为-1,
clkevent:function(s,__this) {
var _this = this;
__this.style.backgroundColor="#ccc";
_this.farr = [];
if(s===-1){//点击到雷时
_this.setHtmlDom2();
$("#result").html("you lose!")
}
},
点击到空白时,显示大片安全区域
这种情况下,需要对周围8个方格继续检测,原理相同;
检测过的方格不应重复检测。
if(s===0){//点击到的方格周围没有雷
var i = $(__this).attr("ai");
var j = $(__this).attr("aj");
_this.check([i,j]);
}
这边比较冗余,分8种进行check;
check:function(arr) {
var _this = this;
var index = isInArray(arr,_this.farr);
if(index===-1){
_this.farr.push(arr);
var i = parseInt(arr[0]);
var j = parseInt(arr[1]);
var len = _this.map[0].length;
var indexli = i*len+j;
var li = $("#map li")[indexli];
$("#map").find(li)[0].style.backgroundColor="#ccc";
if((i-1>=0)&&(j-1>=0)&&(_this.map[i-1][j-1]===0)){
var index = isInArray([i-1,j-1],_this.farr);
if(index===-1){
_this.check([i-1,j-1]);
}
}
else{
(i-1>=0)&&(j-1>=0)&&_this.elsef(i-1,j-1);
}
if((i-1>=0)&&(_this.map[i-1][j]===0)){
var index = isInArray([i-1,j],_this.farr);
if(index===-1){
_this.check([i-1,j]);
}
}
else{
(i-1>=0)&&_this.elsef(i-1,j);
}
if((i-1>=0)&&(j+1<=cols-1)&&(_this.map[i-1][j+1]===0)){
var index = isInArray([i-1,j+1],_this.farr);
if(index===-1){
_this.check([i-1,j+1]);
}
}
else{
(i-1>=0)&&(j+1<=cols-1)&&_this.elsef(i-1,j+1);
}
if((j+1<=cols-1)&&(_this.map[i][j+1]===0)){
var index = isInArray([i,j+1],_this.farr);
if(index===-1){
_this.check([i,j+1]);
}
}
else{
(j+1<=cols-1)&&_this.elsef(i,j+1);
}
if((j-1>=0)&&(_this.map[i][j-1]===0)){
var index = isInArray([i,j-1],_this.farr);
if(index===-1){
_this.check([i,j-1]);
}
}
else{
(j-1>=0)&&_this.elsef(i,j-1);
}
if((i+1<=rows-1)&&(j-1>=0)&&(_this.map[i+1][j-1]===0)){
var index = isInArray([i+1,j-1],_this.farr);
if(index===-1){
_this.check([i+1,j-1]);
}
}
else{
(i+1<=rows-1)&&(j-1>=0)&&_this.elsef(i+1,j-1);
}
if((i+1<=rows-1)&&(_this.map[i+1][j]===0)){
var index = isInArray([i+1,j],_this.farr);
if(index===-1){
_this.check([i+1,j]);
}
}
else{
(i+1<=rows-1)&&_this.elsef(i+1,j);
}
if((i+1<=rows-1)&&(j+1<=cols-1)&&(_this.map[i+1][j+1]===0)){
var index = isInArray([i+1,j+1],_this.farr);
if(index===-1){
_this.check([i+1,j+1]);
}
}
else{
(i+1<=rows-1)&&(j+1<=cols-1)&&_this.elsef(i+1,j+1);
}
}
},
点记到雷旁边时,显示周围雷的个数
else{//点击的到的方格周围有雷,则直接显示数值
__this.innerText = s;
}
这上面是主要代码,游戏非常简易,没有实现右击和鼠标左右键同时点击的检测,只是实现了扫雷最基本的功能。以后或许会优化。下面是整个代码。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
ul{margin: 0;padding: 0;list-style: none;}
ul li{
background-color:#ccc;
width:30px;
height: 30px;
float: left;
border:1px solid #efd;
}
#map{
width: 320px;
}
#ctrl{
text-align: center;
}
#ctrl div{
margin: 12px 0 0 0;
}
.sel{
width: 25%;
border-radius: 25px;
height: 25px;
box-shadow:2px 2px 5px #8B4789
}
</style>
<script type="text/javascript" src="./jquery.min.js"></script>
</head>
<body>
<div class="lei">
<ul id="map">
</ul>
</div>
<div id="ctrl">
<div>
<label id="nums">12</label>
</div>
<div>
<select class="sel" id="range">
<option value="25">25</option>
<option value="20">20</option>
<option value="15">15</option>
</select>
</div>
<div>
<select class="sel" id="diff">
<option value="0.9">very hard</option>
<option value="0.6">hard</option>
<option value="0.3">commom</option>
<option value="0.1">easy</option>
</select>
</div>
<div>
<button id="start" onclick="game.init()">开始</button>
</div>
<div>
<label id="result" style="color:red"></label>
</div>
</div>
<script type="text/javascript">
var game = {
map:[],
warr:[],
farr:[],
rows:0,
cols:0,
init:function() {
var _this= this;
rows = cols = $("#range").val();
var width = rows*32+"px";
$("#map").css({
width:width
})
_this.map = _this.getRandomArray(rows,cols);
_this.setHtmlDom(_this.map);
},
getRandomArray:function(wi,he) {
var diff = $("#diff").val();
var bomb = parseInt(wi*he*diff);
$("#nums").html(bomb);
if(bomb===0){
bomb=2;
}
var maparr=[];
for (var i = 0; i < wi; i++) {
maparr[i] = [];
for (var j = 0; j < he; j++) {
maparr[i][j]=0;
}
}
for (var i = 0; i < bomb; i++) {
var r = getRandomBetween(0,wi);
var c = getRandomBetween(0,he);
maparr[r][c]=-1;
}
for (var i = 0; i < maparr.length; i++) {
for (var j = 0; j < maparr[i].length; j++) {
var a = maparr[i][j]
if(a!==-1){
(i-1>=0)&&(j-1>=0)&&(maparr[i-1][j-1]===-1)&&(a+=1);
(i-1>=0)&&(maparr[i-1][j]===-1)&&(a+=1);
(i-1>=0)&&(j+1<=he-1)&&(maparr[i-1][j+1]===-1)&&(a+=1);
(j+1<=he-1)&&(maparr[i][j+1]===-1)&&(a+=1);
(j-1>=0)&&(maparr[i][j-1]===-1)&&(a+=1);
(i+1<=wi-1)&&(j-1>=0)&&(maparr[i+1][j-1]===-1)&&(a+=1);
(i+1<=wi-1)&&(maparr[i+1][j]===-1)&&(a+=1);
(i+1<=wi-1)&&(j+1<=he-1)&&(maparr[i+1][j+1]===-1)&&(a+=1);
maparr[i][j]=a;
}
}
}
return maparr;
},
setHtmlDom:function(arr) {
var html="";
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
html+='<li class="mli" style="background-color:wheat" ai="'+i+'" aj="'+j+'" val="'+arr[i][j]+'" onclick="game.clkevent('+arr[i][j]+',this)"></li>';
}
}
$("#map").html(html);
},
setHtmlDom2:function() {
var arr = this.map;
var html="";
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
if(arr[i][j]===-1){
html+='<li class="mli" style="background:#eac0ce url(./ball.png);background-size:cover;" val="'+arr[i][j]+'" onclick="game.clkevent('+arr[i][j]+',this)"></li>';
}
else if(arr[i][j]===0){
html+='<li class="mli" style="background-color:efe" val="'+arr[i][j]+'" onclick="game.clkevent('+arr[i][j]+',this)"></li>';
}
else{
html+='<li class="mli" style="background-color:efe" val="'+arr[i][j]+'" onclick="game.clkevent('+arr[i][j]+',this)">'+arr[i][j]+'</li>';
}
}
}
$("#map").html(html);
},
clkevent:function(s,__this) {
var _this = this;
__this.style.backgroundColor="#ccc";
_this.farr = [];
if(s===-1){
_this.setHtmlDom2();
$("#result").html("you lose!")
}
if(s===0){
var i = $(__this).attr("ai");
var j = $(__this).attr("aj");
_this.check([i,j]);
}
else{
__this.innerText = s;
}
},
check:function(arr) {
var _this = this;
var index = isInArray(arr,_this.farr);
if(index===-1){
_this.farr.push(arr);
var i = parseInt(arr[0]);
var j = parseInt(arr[1]);
var len = _this.map[0].length;
var indexli = i*len+j;
var li = $("#map li")[indexli];
$("#map").find(li)[0].style.backgroundColor="#ccc";
if((i-1>=0)&&(j-1>=0)&&(_this.map[i-1][j-1]===0)){
var index = isInArray([i-1,j-1],_this.farr);
if(index===-1){
_this.check([i-1,j-1]);
}
}
else{
(i-1>=0)&&(j-1>=0)&&_this.elsef(i-1,j-1);
}
if((i-1>=0)&&(_this.map[i-1][j]===0)){
var index = isInArray([i-1,j],_this.farr);
if(index===-1){
_this.check([i-1,j]);
}
}
else{
(i-1>=0)&&_this.elsef(i-1,j);
}
if((i-1>=0)&&(j+1<=cols-1)&&(_this.map[i-1][j+1]===0)){
var index = isInArray([i-1,j+1],_this.farr);
if(index===-1){
_this.check([i-1,j+1]);
}
}
else{
(i-1>=0)&&(j+1<=cols-1)&&_this.elsef(i-1,j+1);
}
if((j+1<=cols-1)&&(_this.map[i][j+1]===0)){
var index = isInArray([i,j+1],_this.farr);
if(index===-1){
_this.check([i,j+1]);
}
}
else{
(j+1<=cols-1)&&_this.elsef(i,j+1);
}
if((j-1>=0)&&(_this.map[i][j-1]===0)){
var index = isInArray([i,j-1],_this.farr);
if(index===-1){
_this.check([i,j-1]);
}
}
else{
(j-1>=0)&&_this.elsef(i,j-1);
}
if((i+1<=rows-1)&&(j-1>=0)&&(_this.map[i+1][j-1]===0)){
var index = isInArray([i+1,j-1],_this.farr);
if(index===-1){
_this.check([i+1,j-1]);
}
}
else{
(i+1<=rows-1)&&(j-1>=0)&&_this.elsef(i+1,j-1);
}
if((i+1<=rows-1)&&(_this.map[i+1][j]===0)){
var index = isInArray([i+1,j],_this.farr);
if(index===-1){
_this.check([i+1,j]);
}
}
else{
(i+1<=rows-1)&&_this.elsef(i+1,j);
}
if((i+1<=rows-1)&&(j+1<=cols-1)&&(_this.map[i+1][j+1]===0)){
var index = isInArray([i+1,j+1],_this.farr);
if(index===-1){
_this.check([i+1,j+1]);
}
}
else{
(i+1<=rows-1)&&(j+1<=cols-1)&&_this.elsef(i+1,j+1);
}
}
},
elsef:function(i,j) {
var _this = this;
var len = _this.map[0].length;
var indexli = i*len+j;
var li =$("#map li")[indexli];
var ad = $("#map").find(li)[0].attributes["val"];
$("#map").find(li)[0].style.backgroundColor="#ccc";
$("#map").find(li)[0].innerText = $("#map").find(li)[0].attributes["val"].textContent;
}
}
function getRandomBetween(A,B) {
return Math.floor(Math.random()*(B-A)+A);
}
function isInArray(arr,arrs) {
if(arrs.length===0){
return -1;
}
for (var i = 0; i < arrs.length; i++) {
if(arrs[i][0]==arr[0]&&arrs[i][1]==arr[1]){
return 2;
}
}
return -1
}
game.init();
</script>
</body>
</html>