欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

js原生扫雷(第一版)

程序员文章站 2022-04-07 21:53:35
...

最近痴迷上了扫雷游戏,所以根据一些扫雷的规则,自己 写了一套简易的扫雷游戏,没有参考任何代码,凭自己感觉来的,所以希望大家多提意见

扫雷事项:

               操作: 右击立旗帜,左击打开方格

               逻辑: 1、先生成10个随机雷,然后在点击的时候计算八个方位的雷的数量,得到你的数字

                        2、如果点击到0的位置应该扩散开来,直到有边界为止

                        3、如果将全部雷排除,或者点击到雷,将结束游戏

首先css和html代码

 <style>
        .box{
            width:650px;
            height:100%;
            margin:0 auto;
            display: block;

        }   
        .div{
            height: 60px;
            width: 60px;
            border: 1px solid  #A9A9A9 ;
            float: left;
            text-align: center;
            line-height: 60px;

        }
        .div_origin{
            box-shadow: #A9A9A9 1px 5px 5px;
            background-color: rgb(240,235,213);
            
        }
        .div_lei{
            background:url('img/lei.jpg');background-size:100%;
        }
        .div_number{
            color: red;
            text-align: center;
            line-height: 60px;
        }
        .div_flag{
            background:url('img/flag.png');background-size:100%;

        }
        #button_style{
            height:100px;
            width:200px;
            background-color: rgb(240,235,213);
            box-shadow: #A9A9A9 2px 5px 5px;
            display: block;
        }
        #container
        {
            height: 100%;
            width: 100%;
        }
        #div_alert
        {
            margin: 0 auto;
            height:200px;
            width: 200px;
            background-color: rgb(240,235,213);
            text-align: center;
            line-height: 100px;
            box-shadow: #A9A9A9 2px 5px 5px;
            display: none;
        }
        #button_sure
        {
            background-color: #69c0ff;
            box-shadow: #A9A9A9 2px 5px 5px;
            flex:1;
            margin: 20px;
        }
    </style>
</head>
<body>
    <div id = 'container'>
        <button id = 'button_style' onclick="creatGrid()">开始游戏</button>
        <div id = 'div_alert'>
            <row id = 'row_end'>
            游戏结束
            </row>
            <row  style="display: flex;">
                <button id = 'button_sure' onclick="creatGrid()">确认</button>
            </row>

        </div>
        <div class="box"></div>
        
    </div>
</body>

然后我们先声明一些全局变量

var leiArr = []; //十个随机数雷
    var leiNum; //雷的数量
    var divElements = document.getElementsByClassName('div')
    var isClick = true;  // 是否点击开始
    var box = document.getElementsByClassName('box')[0];
    var button = document.getElementById('button_style');
    box.style.display = 'block'  
    var direction = [[0,1],[0,-1],[1,0],[1,-1],[1,1],[-1,-1],[-1,0],[-1,1]]; //八个方位
    var length = direction.length;
    var alert = document.getElementById('div_alert');

我将八个方位写成一个二维数组的样子,这样方便我们采用广度搜索来遍历这八个方位

首先我们生成100个格子,并且生成10个随机雷,将点击事件的监听函数写入

function creatGrid() //生成100个格子
    {
        if(!isClick)
        {
           window.location.reload()
        }
        else
        {
            button.innerHTML = '重新开始'
        }
        isClick = !isClick;
        leiNum = 10;
        for(i=0;i<leiNum;i++) //生成10个不重复的100以内的随机数
        {
            var randomNum = Math.floor(Math.random()*99)+1;
            if(leiArr.indexOf(randomNum) === -1){
                leiArr.push(randomNum);            
            }else{                 
                i= i - 1;
                continue;
            }
        }
        for(i=1;i<=10;i++)
        {
            for(j=1;j<=10;j++)
            {
                var div = document.createElement('div');
                (function (x,y){//右键监听
                    div.addEventListener('contextmenu',function(event){
                    event.preventDefault();//阻止右键的默认事件
                    handleFlag(x,y,event.target);
                    },false)
                    div.addEventListener('click',function(event){//点击监听
                    handleShow(x,y,event.target)
                    },false) 
                })(i,j)

                div.className = 'div';
                div.classList.add('div_origin');
                box.appendChild(div);
            }
        }

    }

其次我们来处理当点击左键的时候,方格的显示情况 

 function handleShow(x,y,obj) //处理每个方格的展示
    {
        var isFlagDiv = obj.className.indexOf('div_flag')
        if(isFlagDiv === -1) //是否已右键插入旗帜
        {
        var resultNumber = handlenumber(x,y); //此处八个方位的雷的数量

            if(resultNumber === 100)  //若为雷
            {
                obj.classList.add('div_lei');
                obj.classList.remove('div_origin');
                setTimeout(function()
                {
                    alert.style.display = 'block'
                    box.style.display = 'none';}, 100);
                }
            else
            {   
                obj.classList.remove('div_origin');
                obj.classList.add('div_number');
                obj.innerHTML = resultNumber;
                if(resultNumber === 0)  //当遇到0 的时候,扩散开来
                {
                    for(var i = 0;i < length;i++)
                    {
                        var u = x + direction[i][0];
                        var w = y + direction[i][1];
                        var tagetDiv = divElements[(u-1)*10+w-1];
                        if(tagetDiv!== undefined && w < 11 &&w>0&&u < 11 &&u>0)
                        {
                            if(tagetDiv.innerHTML=== '') //此处方格并未有数字显示,就是未遍历
                            {
                                handleShow(u,w,tagetDiv);
                            }
                        }
                    }
                }
                var span = document.createElement = ('span');
            }
        }   
    }

计算八个方位的雷的数量 

 function handlenumber(i,j)  //计算每个方格八个方位的雷数量
    {
        var x = i;
        var y = j;
        var number = 0;
        number = (i - 1) * 10 + j;
        if(leiArr.indexOf(number)!==-1)
        {
           return 100;
        }
        else
        {
            number = 0;
            for(var k = 0;k < length;k++)
            {
                x = i + direction[k][0];
                y = j + direction[k][1];
                if(x <11&&y<11&&x>0&&y>0)
                {
                    var res = (x - 1) * 10 + y;
                    if(leiArr.indexOf(res)!==-1)
                    {
                        number++;
                    }
                }
            }
        return (number);
        }
    }

右击插旗标志雷的数量

 function handleFlag(x,y,obj) //处理旗子标志
    {
        var row = document.getElementById('row_end');
        var isNumberDiv = obj.className.indexOf('div_number')
        var isFlagDiv = obj.className.indexOf('div_flag');
        if(isNumberDiv === -1)
        {
            (isFlagDiv === -1 )?obj.classList.add('div_flag'):obj.classList.remove('div_flag');
            var tagetDiv = (x - 1) * 10 + y;
            if(leiArr.indexOf(tagetDiv)!==-1 )
            {
                (isFlagDiv === -1)?leiNum--:leiNum++;
            }
        }
        if(leiNum === 0)
        {
            setTimeout(function()
                {
                    alert.style.display = 'block';
                    row.innerHTML = '恭喜成功';
                    box.style.display = 'none';}, 100);   
        }
    }

效果展示:

js原生扫雷(第一版)

码云地址    https://gitee.com/zouling/js_native_mine_clearance

待改进:  1.用户可选择难度:(100格子,还是1000等),

              2.代码冗余可改进,界面提示改进.

相关标签: 扫雷