zoukankan      html  css  js  c++  java
  • 原生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方格
  • 相关阅读:
    dlib库+vs2017详细配置流程
    【网易云课堂】【中科院团队】深度学习:算法到实战——神经网络基础
    【网易云课堂】【中科院团队】深度学习:算法到实战——绪论
    matlab 读取多行txt文本
    LeetCode 228. Summary Ranges【未加入列表】
    LeetCode 438. Find All Anagrams in a String
    c++冷知识
    python项目实战——西游记用字统计
    LeetCode 101. Symmetric Tree
    LeetCode 63. Unique Paths II
  • 原文地址:https://www.cnblogs.com/hunter1/p/13098961.html
Copyright © 2011-2022 走看看