原生JS扫雷

作为继贪吃蛇练手后的第二个练习五子棋着实有点难,由于训练不多,主要是学习的视频教学
不多说了直接看效果发代码在这里插入图片描述
html代码

在这里插入代码片
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../css/index.css">
</head>

<body>
    <div id="content">
        <div class="level">
            <button class="active">初级</button>
            <button>中级</button>
            <button>高级</button>
            <button>重新开始</button>
        </div>

        <div class="gameBox">

        </div>
        <div class="mineNum">
            剩余雷数 :<span class="numberLeishu"></span>
        </div>
    </div>
    <script src="../js/index.js"></script>
</body>

</html>

css代码

#content{
    margin:50px auto;
}
.level{
    text-align: center;
    margin: 10px;
}
.level button{
    padding: 5px 15px;
    background: #02a4ad;
    border: none;
    color: #fff;
    border-radius: 3px;
    outline:none;
    cursor: pointer;
}
.level button.active{
    background: #00abff;
}
.mineNum{
    margin-top:10px;
    text-align:center;
}
table{
    border-spacing: 1px;
    background: #929196;
    margin:0 auto;
}
td{
    padding: 0;
    width:20px;
    height:20px;
    background:#ccc;
    border:2px solid;
    border-color: #fff #a1a1a1 #a1a1a1 #fff;
    text-align: center;
    line-height: 20px;
    font-weight: bold;
}
.mine{
    background: #d9d9d9 url(../images/dl.png);
    background-size: cover;
}

.flag{
    background: #ccc url(../images/hq.png);
    background-size: cover;
}
td.zero{
    border-color: #d9d9d9;
    background: #d9d9d9;
}
td.one{
    border-color: #d9d9d9;
    background: #d9d9d9;
    color:#0332fe;
}
td.two{
    border-color: #d9d9d9;
    background: #d9d9d9;
    color: #019f02;
}
td.three{
    border-color: #d9d9d9;
    background: #d9d9d9;
    color: #ff2600;
}
td.four{
    border-color: #d9d9d9;
    background: #d9d9d9;
    color: #93208f;
}
td.five{
    border-color: #d9d9d9;
    background: #d9d9d9;
    color: #ff7f29;
}
td.six{
    border-color: #d9d9d9;
    background: #d9d9d9;
    color: #ff3fff;
}
td.seven{
    border-color: #d9d9d9;
    background: #d9d9d9;
    color: #3fffbf;
}
td.eight{
    border-color: #d9d9d9;
    background: #d9d9d9;
    color:#22ee0f;
}

js代码

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

    this.squares = [];//一个二维数组,按照行和列的方式放雷
    this.tds = [];      //存储所有单元格的DOM
    this.surplusMine = mineNum;      //剩余雷的数量
    this.allRight = false;      //右击标出来的小红旗是否全是雷 用来判断游戏是否成功
    this.parent = document.querySelector('.gameBox');

}
Mine.prototype.randomNum = function () {
    var square = new Array(this.tr * this.td);//生成一个空数组但是有长度,长度为格子的总数
    for (var i = 0; i < square.length; i++) {
        square[i] = i;
    }
    square.sort(function () {
        return 0.5 - Math.random()
    })
    return square.slice(0, this.mineNum);
}

Mine.prototype.init = function () {
    // console.log(this.randomNum());
    var rn = this.randomNum();    //雷在格子里的位置
    var n = 0; //用来找到格子对应的索引
    for (var i = 0; i < this.tr; i++) {
        this.squares[i] = [];
        for (var j = 0; j < this.td; j++) {
            // this.squares[i][j] = 
            n++;
            //取一个方块在数组里的数据要是用行和列的方式去取
            //找方块周围的数字要用坐标的形式去取,(行和列的形式与坐标形式恰好相反)
            if (rn.indexOf(n) != -1) {
                // 如果这个条件成立,说明现在循环到这个索引在雷的数组里找到了,那就表示这个索引对应的是个雷
                this.squares[i][j] = { type: 'mine', x: j, y: i };
            } else {
                this.squares[i][j] = { type: 'number', x: j, y: i, value: 0 };
            }
        }
    }

    // console.log(this.squares);
    this.updataNum();
    this.creatDom();
    this.parent.oncontextmenu = function () {
        return false;
    }
    //剩余雷数
    this.mineNumDom = document.querySelector('.numberLeishu');
    this.mineNumDom.innerHTML = this.surplusMine;
};

//创建表格
Mine.prototype.creatDom = function () {
    var This = this;
    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');
            // domTd.innerHTML = 0;
            domTd.pos = [i, j];//把格子对应的行和列存到格子身上,为了下面通过这个值去数组里取得相应的数据
            domTd.onmousedown = function () {
                This.play(event, this)//This指的是实例对象,this指的是年级的那个td

            }
            this.tds[i][j] = domTd;   //这里把用DOM所创建的td添加到数组当中
            // if (this.squares[i][j].type == 'mine') {
            //     domTd.className = 'mine';
            // }
            // if (this.squares[i][j].type == "number") {
            //     domTd.innerHTML = this.squares[i][j].value;
            // }

            domTr.appendChild(domTd);
        }
        table.appendChild(domTr);
    }
    this.parent.innerHTML = '';//类似于清屏功能
    this.parent.appendChild(table);
};

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]);
        }
    }
    return result
};
//更新所有数字
Mine.prototype.updataNum = function () {
    for (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++) {
                // num[i] == [0, 1]
                // num[i][0] = 0;
                // num[i][1] = 1
                this.squares[num[k][0]][num[k][1]].value += 1;
            }
            // console.log(num);
        }
    }
    // console.log(this.squares);
}

// x-1,y-1     x,y-1     x+1,y-1
// x-1,y       x,y       x+1,y
// x-1,y+1     x,y+1     x+1,y+1

//找周围的8个方格

Mine.prototype.play = function (ev, obj) {
    var This = this;
    if (ev.which == 1) {
        //点击的是左键
        // console.log(obj);   
        var curSquare = this.squares[obj.pos[0]][obj.pos[1]];
        var cl = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'];
        // console.log(curSquare);
        if (curSquare.type == "number") {
            obj.innerHTML = curSquare.value;
            obj.className = cl[curSquare.value];
            if (curSquare.value == 0) {
                //点到数字0的情况
                //1、显示自己 
                //2、找四周
                // 1、显示四周(如果四周的值有不为0即停止)
                // 2、如果为0
                //     1、显示四周(如果四周的值有不为0即停止)
                //     2、如果为0
                //         1、显示四周(如果四周的值有不为0即停止)
                //         2、如果为0
                //             1、显示四周(如果四周的值有不为0即停止)
                //             2、如果为0

                obj.innerHTML = ''
                function getAllzero(square) {
                    var around = This.getAround(square);//找到了周围的n个格子

                    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) {//递归条件
                            // getAllzero(This.squares[x][y]);
                            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);

                //点到非0
            }
        } else {
            // console.log('点到雷了');    
            this.gameOver(obj);
        }
    }

    //点击的邮件
    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) {
            if (this.allRight) {
                alert('恭喜过关');
            } else {
                alert('游戏失败');
            }
        }
    }

};

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 = '#f00';
    }
}
// 上边button的功能
var btns = document.querySelectorAll('.level button');
var mine = null;
var ln = 0;
var arr = [[9, 9, 10], [16, 16, 40], [28, 28, 99]];
for (let i = 0; i < btns.length - 1; i++) {
    btns[i].onclick = function () {
        btns[ln].className = '';
        this.className = 'active';
        mine = new Mine(...arr[i]);
        mine.init();
        ln = i;
    }
}
btns[0].onclick();//初始化
btns[3].onclick = function(){
    mine.init();
}
// var mine = new Mine(20, 20, 10);
// mine.init();

// console.log(mine.getAround(mine.squares[0][0]));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值