原生js实现扫雷游戏

展示页面:https://shalltears.github.io/sweep-Mine/ ;

源码下载页面:https://download.csdn.net/download/zmdmwh/10816787

截图:最后是胜利的滚动效果。

 

画布就不说了,使用的是相当于二维数组的一个9乘9的数组。

1.如何创建地雷(保证10个)

        首先两个0-9的随机数,创建随机二维坐标赋值给数组,然后创建一个字符串去重函数如下:

disArr: function (str) {//字符串去重
        var obj = {};
        var sum = [];
        var arr = str.split('_');
        for (i = 0; i < arr.length; i++) {
            if (obj[arr[i]] == undefined) {
                obj[arr[i]] = 'seat';//占位
            }
        }
        for (var pop in obj) {
            sum.push(pop.split(''));
        }
        return sum;
    }

        根据出来的去重数组长度来判断生成随机地雷是否有重复,然后使用while循环,不足10个就要接着生成。

2.如何把周围地雷的数量给标注上

        使用两个for循环,遍历二维数组,如果这个这个元素是地雷(我用999来代表是地雷),那么它周围的8个元素的值全部+1,循环走完就得到一个类似扫雷地图的二维数组,999是地雷,数字代表雷的数目,使用try是防止越界报错,越界自动不执行。

for (var i = 0; i < 9; i++) {
            for (var j = 0; j < 9; j++) {
                var cont = 0;
                if (this.main[i][j] == 999) { continue; }
                try { this.main[i - 1][j - 1] == 999 ? cont++ : 0 } catch{ }
                try { this.main[i - 1][j] == 999 ? cont++ : 0 } catch{ }
                try { this.main[i - 1][j + 1] == 999 ? cont++ : 0 } catch{ }
                try { this.main[i][j - 1] == 999 ? cont++ : 0 } catch{ }
                try { this.main[i][j + 1] == 999 ? cont++ : 0 } catch{ }
                try { this.main[i + 1][j - 1] == 999 ? cont++ : 0 } catch{ }
                try { this.main[i + 1][j] == 999 ? cont++ : 0 } catch{ }
                try { this.main[i + 1][j + 1] == 999 ? cont++ : 0 } catch{ }
                this.main[i][j] = cont;
            }
        }

3.如何把数组转换成方格放在界面

        这里同样使用两个for循环,第一个循环可以创建9个ul,第二个循环在每个ul里生成9个li,根据不同的数字给li们用setAttribute增加上不同的类名(可以设置不同数值的样式,后面这个类名还可以区分是不是雷)。

for (var i = 0; i < 9; i++) {
            var ul = document.createElement('ul');
            for (var j = 0; j < 9; j++) {
                var li = document.createElement('li');
                switch (this.main[i][j]) {
                    case 0: li.setAttribute('class', 'li-0'); break;
                    case 1: li.setAttribute('class', 'li-1'); break;
                    case 2: li.setAttribute('class', 'li-2'); break;
                    case 3: li.setAttribute('class', 'li-3'); break;
                    case 4: li.setAttribute('class', 'li-4'); break;
                    case 5: li.setAttribute('class', 'li-5'); break;
                    case 6: li.setAttribute('class', 'li-6'); break;
                    case 999: li.setAttribute('class', 'li-999'); break;
                }
                ul.appendChild(li);
            }
            this.map.appendChild(ul);
        }

4.点击后的扩散

        在点击事件中增加如下判断:

parseInt(this.getAttribute('class').substring(3)) == 999 ? sweepMine.fail() : sweepMine.goOn(li, i);

        不是雷的话就去执行goOn; goOn里有两部分,①先把当前点击的方格的数值显示出来,当然可以把它的类名截取出来赋值上就行了。②是边界判断,因为这里获取的是81个li,不是二维数组了,所以要加个边界判断,我这里只是很简单的把边界调出来分别处理了,再次调用当前位置的上下左右八个方格的点击事件就完成了扩散的效果。

        为什么数值不为0的会停止扩散呢?因为不为0的在goOn的前面被拦截下来了,不为0就只是把状态设为1,然后显示数值。

        还有两个需要注意的地方:

        1.要使用try catch,因为访问元素可能会越界,越界后不加处理就可以了;

        2.要加入状态位,被点击后的li要把状态位设为1,不然扩散时会有很多重复的操作影响性能。

5.结尾

        剩下的就是较简单的逻辑优化有初始化了,在不同操作的时候有对应的不通操作,比如重新开始后怎么样,失败和胜利后怎么样,只要把流程多走几遍就能优化的差不多了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值