原生js扫雷游戏

图片效果如下:完整代码:https://pan.baidu.com/s/15WjcsmuXULciCZrlhiOMoQ 密码:g4my

1.功能:

  实现的功能:

    1.选择游戏难度

    2.右击标记地雷(右击两次可以取消标记)

    3.显示剩余雷数

    4.自动连锁点开(点击到周围格子都为空时,自动将周围格子显示)

  没有实现的功能:

    1.没有时间限制

2.开始步入正题

  第一步:生成一张地图,也就是td表格

  第二步:生成表格里面的雷并且显示到页面(生成不重复的数字,然后将其顺序打乱,最后截取所需雷数)

  第四步:点击雷,获取到雷附近的信息(获取以雷为中心,周围九宫格的坐标)

  第五步:以雷为中心,将周围九宫格里面的数字实现累加

  第六步:设置鼠标点击事件,当点击右键是标记小红旗,左键来判断是否为雷

  第七步:点击button按钮,实现不同难度之间的切换

3.首先要生成一张地图,创建一个构造函数Mine,里面存储的是一些一会要用到的变量

function Mine(tr,td,mineNum){
this.tr=tr;                  //行
this.td=td;                  //列
this.mineNum=mineNum;            //雷的数量

this.squares=[];                //存储所有方块的信息,它是一个二维数组,
this.tds=[];                  //存储所有的单元格(二维数组)
this.surplusMine=mineNum;          //剩余雷的数量
this.allRight=false;             //右击标的小红旗是否全是雷,用来判断游戏是否成功

this.parent=document.querySelector('.gameBox');
}

  接下来要在构造函数Mine的原型链上创建一个方法,用来创建表格(生成地图)

Mine.prototype.createDom=function(){
    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');//创建td
            
            this.tds[i][j]=domTd;           //将所有的td存储到tds里面,后面会用到
            domTr.appendChild(domTd);        //将td添加到tr里面
        }
        table.appendChild(domTr);           //将tr添加到表格里面
    }
    this.parent.appendChild(table);          //将表格显示在页面
}

4.生成不重复的数字,截取所需要的数字,就是雷

Mine.prototype.randomNum=function(){
    var square=new Array(this.tr*this.td);      //生成一个空数组,就是生成位置,长度为格子的总数
    for(var i=0;i<square.length;i++){
        square[i]=i;                            //生成81个数字,相当于81个索引    
    }    
//    console.log(square);
square.sort(function(){return 0.5 - Math.random()});//将生成的数字打乱  
    return square.slice(0,this.mineNum);        //将生成的81个数字截取为9个数字
}

效果如下:

5.以雷为中心,获取周围九宫格的坐标,用来使雷周围的数字发生改变

Mine.prototype.getAround=function(square){
    var x=square.x;
    var y=square.y;
    var result=[];                            //存储九宫格坐标(二维数组)
    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]);                //将九宫格里面符合条件的数组添加到result里面
        }
    }
    return result;                  //将坐标返回
}

6.将雷周围的数字实现累加,方便玩家判断雷的位置

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++){
//                console.log(num);
                this.squares[num[k][0]][num[k][1]].value+=1;//将每个格子的value值累加
            }
        }
    }

7.设置鼠标左键右键,当点击左键时,判断点击的是否为雷,如果为0,继续判断周围是否为零,实现连锁效果,右击标小红旗。

Mine.prototype.play=function(ev,obj){ 
var
This=this;                                             //判断是左键还是右键                                               //obj==this==td if(ev.which==1&&obj.className!='flag'){                    //等于1时,为左键并且限制用户标完小红旗后不能左击 //console.log(obj); var curSquare=this.squares[obj.pos[0]][obj.pos[1]];           //获取当前格子的信息;this.pos[0]等于这个格子的pos0的值 var cl=['zero','one','two','three','four','five','six','seven','eigth']; //console.log(cl[3]); //console.log(curSquare);                                         if(curSquare.type=='number'){                      //区分是雷还是数字                                      //当用户点击的是数字 obj.innerHTML=curSquare.value;                    //将数字显示出来 obj.className=cl[curSquare.value];                //改变不同的数字的显示颜色 //还要区分数字是0还是非零,当点到零时,要使周围都显示 if(curSquare.value==0){                        //点击的格子是否为零 obj.innerHTML='';                         //将为零的显示为空 function getAllZero(square){                  //递归函数 var around=This.getAround(square);              //获取当前点击的周围格子数组 //console.log(around); for(var i=0;i<around.length;i++){ var x=around[i][0]; var y=around[i][1]; This.tds[x][y].className=cl[This.squares[x][y].value]; if(This.squares[x][y].value==0){          //以某个格子为中心,找到周围格子为零 if(!This.tds[x][y].check){ This.tds[x][y].check=true; getAllZero(This.squares[x][y]); } }else{                          //以某个格子为中心,找的周围的格子不为零 This.tds[x][y].innerHTML=This.squares[x][y].value; } } } getAllZero(curSquare); } }else{                                  //用户点击的是雷 this.gameOver(obj); setTimeout(function(){ alert('失败');                            //alert会优先执行,使用定时器,使先显示雷,后弹框 },200); } } if(ev.which==3){                                         //如果右击的是一个数字,就不能右击 if(obj.className&&obj.className!='flag'){ return; } obj.className=obj.className=='flag'?'':'flag';             //右击两次,使红旗变化 if(this.squares[obj.pos[0]][obj.pos[1]].type=='mine'){ this.allRight=true;                           //用户标的小红旗都是雷 }else{ this.allRight=false;                          //用户标的其中有一个雷 } if(obj.className=='flag'){ this.mineNumDom.innerHTML=--this.surplusMine; }else{ this.mineNumDom.innerHTML=++this.surplusMine; } if(this.surplusMine==0){                                       //剩余的雷的数量为0,表示用户自己已经标完小红旗,这时候要判断游戏是成功还是结束 if(this.allRight==true){                        //表示标的小红旗都是雷 alert('恭喜你,游戏通过'); }else{ alert('游戏失败'); this.gameOver();                          //游戏失败就会将所有的雷显示出来 } } } };

Mine.prototype.gameOver=function(clickTd){
    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='red';                       //给点中的那个雷表上小红色

        }
    }

}

 

连锁效果:

 

8.实现button按钮的不同切换

var btns=document.querySelectorAll('.level button');
var mine=null;                    //用来存储生成的实例
var ln=0;                        //用来处理当前显示的状态
var arr=[[9,9,10],[16,16,40],[28,28,99]];


//给button添加事件
for(let i=0;i<btns.length;i++){
    if(i<=2){
    btns[i].onclick=function(){
        btns[ln].className='';
        this.className='active';
        mine=new Mine(arr[i][0],arr[i][1],arr[i][2]);
    //console.log(mine);
        mine.init();
        ln=i;
        }
    }else{
        btns[i].onclick=function(){
            mine=new Mine(arr[ln][0],arr[ln][1],arr[ln][2]);
        mine.init();
        }
    }
}



btns[0].onclick();                    //默认显示9*9方格
原文地址:https://www.cnblogs.com/hunter1/p/13098961.html