js版扫雷游戏

本文实例为大家分享了js版扫雷游戏的具体代码,供大家参考,具体内容如下

界面

考虑到简单,一般,困难三个扫雷区域的格子数都不同,所以界面上的扫雷区域是用js动态生成。
先搭好整体html框架:

<div class="container">
        <div class="level">
            <button class="select">简单</button>
            <button>一般</button>
            <button>困难</button>
            <button>重新开始</button>
        </div>
        <div class="mine">
            //扫雷区域
        </div>
        <div class="last">总共雷数 : <span class="mineNum"></span></div>
</div>

首先写一个MineSweeper()构造方法:

function MineSweeper(tr, td, mineNum) {
    this.tr = tr; //行
    this.td = td; //列
    this.mineNum = mineNum; //雷数
    this.area = [];  //存取每个格子信息
    this.doms = [];  //存储格子DOM,用来动态创建DOM
    this.lastMineNum = mineNum; //剩余雷数

    this.parent = document.querySelector('.mine');
    this.num = document.querySelector('.last .mineNum');
}

扫雷区域用一个二维数组表示并存储:

/*
* 扫雷游戏区域area(二维数组)
* [
*      [type: mine/number, x1, y1],
*      [type: mine/number, x2, y2],
*       ... ,
*      [type: mine/number, xn, yn]
* ]
*/

其中type有两个值,mine表示当前格子是一个雷;number表示当前格子是一个数字。
在构造方法的原型上添加方法创建DOM表格,用来动态生成扫雷区域界面:

MineSweeper.prototype.create = function() {
    var _this = this;
    var table = document.createElement('table');
    for(var i = 0; i < this.tr; i++) {
        var trDom = document.createElement('tr');
        //创建行
        this.doms[i] = [];
        for(var j = 0; j < this.td; j++) {
            //创建列
            var tdDom = document.createElement('td');
            this.doms[i][j] = tdDom;
            trDom.appendChild(tdDom); //往行中添加列
        }
        table.appendChild(trDom);//往table中添加行
    }
    this.parent.appendChild(table); //将table添加到界面
};

JS

function MineSweeper(tr, td, mineNum) {
    this.tr = tr; //行
    this.td = td; //列
    this.mineNum = mineNum; 
    this.area = []; 
    this.doms = []; 
    this.lastMineNum = mineNum; 
    this.parent = document.querySelector('.mine');
    this.num = document.querySelector('.last .mineNum');
}
//初始化
MineSweeper.prototype.init = function() {
    var rn = this.randomNum(); //获得type: mine 的索引
    var n = 0; //记录格子索引
    for(var i = 0; i < this.tr; i++) {
        this.area[i] = [];
        for(var j = 0; j < this.td; j++) {
            n ++;
            if(rn.indexOf(n) !== -1) {
                this.area[i][j] = {
                    type: 'mine',
                    x: j,
                    y: i
                };
            } else {
                this.area[i][j] = {
                    type: 'number',
                    x: j,
                    y: i,
                    value: 0
                };
            }
        }
    }
    // console.log(this.area);
    this.num.innerHTML = this.mineNum; //初始化雷数
    this.parent.oncontextmenu = function() {
        return false; //阻止右击菜单事件
    }
    this.updateNumber();
    //创建表格
    this.parent.innerHTML = "";
    this.create();
}

//创建DOM表格
MineSweeper.prototype.create = function() {
    var _this = this;
    var table = document.createElement('table');
    for(var i = 0; i < this.tr; i++) {
        var trDom = document.createElement('tr');
        this.doms[i] = [];
        for(var j = 0; j < this.td; j++) {
            var tdDom = document.createElement('td');
            this.doms[i][j] = tdDom;
            trDom.appendChild(tdDom);

            tdDom.pos = [i, j];
            tdDom.onmousedown = function(event) {
                if(event.button === 0) {  //鼠标左键
                    var curArea = _this.area[this.pos[0]][this.pos[1]];
                    console.log(curArea)
                    if(curArea.type === 'mine') {
                        // console.log('踩到雷了!')
                        this.className = 'mine';
                        _this.gameOver(this);
                        
                    } else {
                        // console.log('is number')
                        if(!curArea.value) {  //踩到0,出现一大片
                            // console.log(0);
                            this.className = 'select'; //先显示自己
                            this.innerHTML = '';
                            
                            function getAllZero(area) {
                                var around = _this.mineAround(area); //找其周围的格子
                                for(var i = 0; i < around.length; i++) {
                                    var x = around[i][0]; //行
                                    var y = around[i][1]; //列
                                    _this.doms[x][y].className = 'select';
                                    if(!_this.area[x][y].value) {
                                        if(!_this.doms[x][y].isHas) {  
                                            _this.doms[x][y].isHas = true; //标记被找过的元素,避免格子重复重复被调用,导致内存资源被滥用
                                            arguments.callee(_this.area[x][y])
                                        }
                                    } else {
                                        _this.doms[x][y].innerHTML = _this.area[x][y].value;
                                    }
                                }
                            }
                            getAllZero(curArea);

                        } else {
                            this.className = 'select';
                            this.innerHTML = curArea.value;
                        }
                        
                    }
                
                } else if(event.button === 2) {  //鼠标右键
                    this.className = this.className == 'flag'? '':'flag';
                    //标记小旗子,则剩余雷数-1
                    if(this.className === 'flag') {
                        _this.num.innerHTML = --_this.lastMineNum;
                    } else {
                        _this.num.innerHTML = ++_this.lastMineNum;
                    }
                }
            }
        }
        table.appendChild(trDom);
    }
    this.parent.appendChild(table);
};

//生成指定数量的不重复的数字
MineSweeper.prototype.randomNum = function() {
    var mineArr = new Array(this.tr*this.td); //该数组用来存储所有格子下标
    for(var i = 0; i < mineArr.length; i++) {
        mineArr[i] = i;
    }

    mineArr.sort(function() {return 0.5 - Math.random()}); //将数组乱序排序
    return mineArr.slice(0, this.mineNum); //随机取得放置雷的下标
};

//找目标格子周围的格子, 雷周围的格子都需要number++
MineSweeper.prototype.mineAround = function(target) {
    var x = target.x;
    var y = target.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.area[j][i].type === 'mine'    
              ){
                continue;
            }
            result.push([j, i]);
        }
    }
    return result; 
};

//更新所有数字
MineSweeper.prototype.updateNumber = function() {
    for(var i = 0; i < this.tr; i++) {
        for(var j = 0; j < this.td; j++) {
            if(this.area[i][j].type == 'number') {
                continue;
            }
            var nums = this.mineAround(this.area[i][j]);  //获取雷周围的格子
            for(var k = 0; k < nums.length; k++) {
                //雷周围的格子的number都要+1
                this.area[nums[k][0]][nums[k][1]].value += 1;
            }
        }
    }
};

//gameOver
MineSweeper.prototype.gameOver = function(downMine) {
    for(var i = 0; i < this.tr; i++) {
        for(var j = 0; j < this.td; j++) {
            if(this.area[i][j].type === 'mine') {
                this.doms[i][j].className = 'mine';
            }
            this.doms[i][j].onmousedown = null;
        }
    }
    if(downMine) {
        downMine.style.backgroundColor = '#f40';
    }

}
function startGame() {
    var btn = document.querySelectorAll('.container .level>button');
    var arr = [[10,10,15],[15,15,40],[20,20,80]];
    var select = 0; //当前选中状态的按钮
    var mine = null;
    for(let i = 0; i < btn.length - 1; i++) {
        console.log(i);
        console.log(arr);
        btn[i].onclick = function(e) {
            btn[select].className = '';
            this.className = 'select';
            select = i;
            mine = new MineSweeper(...arr[i]);
            console.log(arr[i]);
            mine.init();
        }

    }
    btn[0].onclick();
    btn[3].onclick = function() {
        mine.init();
    }
}
startGame();

CSS

.container {
    margin: 30px auto;
    text-align: center;
}
.container .level button {
    background-color: #e5c1cd;
    outline-style: none;
    border: none;
    cursor: pointer;
    color: #fff;
}
.container .level button.select {
    background-color: #b6b4c2;
}
.container .mine table {
    border-spacing: 1px;
    margin: 10px auto;
}
.container .mine table td {
    width: 18px;
    height: 18px;
    padding: 0;
    background-color: #bfb8da;
    border: 2px solid;
    border-color: #ebd7d4 #a56781 #a56781 #ebd7d4;
    text-align: center;
    line-height: 16px;
    font-weight: bold;
}
.container .mine table td.select,
.container .mine table td.mine {
    background-color: #bfb8da;
    border: 1px solid #ebd7d4;
}
.container .mine table td.mine {
    background-image: url("../image/mine.png");
    background-repeat: no-repeat;
    background-size: cover;
}
.container .mine table td.flag {
    background-image: url("../image/flag.png");
    background-repeat: no-repeat;
    background-size: cover;
}
.container .last {
    color: #d87f81;
}

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>MineSweeper</title>
    <link rel="stylesheet" href="./css/index.css">
</head>
<body>
    <div class="container">
        <div class="level">
            <button class="select">简单</button>
            <button>一般</button>
            <button>困难</button>
            <button>重新开始</button>
        </div>
        <div class="mine">
            
        </div>
        <div class="last">总共雷数 : <span class="mineNum"></span></div>
    </div>
<script src="./js/index.js"></script>
</body>
</html>

更新数字

遍历扫雷区域数组,当遇到雷时,取到其周围的格子,如果是数字,则number都+1;如果是雷,则该格子不作操作。

MineSweeper.prototype.updateNumber = function() {
    for(var i = 0; i < this.tr; i++) {
        for(var j = 0; j < this.td; j++) {
            if(this.area[i][j].type == 'number') {
                continue;  //遇到数字格子跳过,不需要取其周围的格子
            }
            var nums = this.mineAround(this.area[i][j]);  //获取雷周围的格子
            for(var k = 0; k < nums.length; k++) {
                //雷周围的格子的number都要+1
                this.area[nums[k][0]][nums[k][1]].value += 1;
            }
        }
    }
};

实现效果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • js实现扫雷小程序的示例代码

    初学javascript,写了一个扫雷程序练练手! 扫雷规则及功能 扫雷想必大家都不陌生,就是windows上点击排雷的小游戏,它的主要规则有 1.左键点击显示当前格子是否为雷,如果为雷的话,GameOver啦,如果不是雷的话,这个格子会显示周围八个格子内的雷数量. 2.鼠标右键标记,标记可能的雷,标记了之后取消需要再次右键点击该格子,左键无效果. 3.鼠标中键(滚轮)按下后,快捷扫雷(如果周围雷数和未被标记且未被翻开的格子相等,会将这些格子一并翻开) 主要功能基本完全复刻了windows7扫雷

  • js实现扫雷源代码

    经过一段时间学习,对javascript有了一个初步的了解自己制作了一个扫雷,源代码+详细注释放在后面,先看下效果图. 初始化界面: 游戏界面: 难易程度切换: 游戏结束: 思路 采用构造函数的形式进行全局开发 生成游戏棋盘 利用双层for循环创建设定的棋盘大小 为每个单元格的dom元素创建一个属性,该属性用于保存单元格的所有信息,如x,y坐标,value,是否为雷等 随机生成炸弹 利用随机数,随机生成炸弹x,y坐标,并将符合该坐标信息的单元格的属性更改为雷 炸弹是在用户第一次点击的时候生成,防

  • JavaScript制作windows经典扫雷小游戏

    代码其实很简单,这里就不多废话了 <html> <head> <meta http-equiv="Content-Language" content="zh-cn"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>扫雷-JavaScript Mine Sweeper

  • 使用纯javascript实现经典扫雷游戏

    很久以前写的 当时都没写注释的 刚加上了 (尼玛,好多自己都不认识了 ... ) 不足的地方就是本来想写个游戏排名的统计的,等有空了再加上(好像每次都这么说 然后就等好久好久...) 还有就是没有实现:点击第一个格子不能是雷的功能 <style> ul{padding:0;list-style:none;} #mine{overflow:hidden;width:30px;height:30px;border:1px solid #966;} #mine li{float:left;width

  • javascript 扫雷游戏

    "); for (var i = 0; i "); for(var j = 0; j   "); buffer.append(" "); } buffer.append(" "); var workarea = document.getElementById("workarea"); workarea.innerHTML = buffer.toString(); mine(); // lay mines at the

  • js版扫雷实现代码 原理不错

    效果图:以下代码复制粘贴到记事本后保存为.html文件,打开后会出现提示,右击允许即可: 寻雷-----by 魅月 var data=new Array( [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0

  • JavaScript版经典游戏之扫雷游戏完整示例【附demo源码下载】

    本文实例讲述了JavaScript扫雷游戏.分享给大家供大家参考,具体如下: 翻出年初写的游戏贴上来,扫雷相信大家都玩过,先上图: 源码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.or

  • HTML+JavaScript实现扫雷小游戏

    本文实例为大家分享了JavaScript实现扫雷小游戏的具体代码,供大家参考,具体内容如下 工具:Sublime Text / Dreamweaver /Hbuilder <!doctype html> <html> <head> <meta charset="utf-8"> <title>SaoLei</title> <style type="text/css"> table {

  • js实现简单扫雷

    本文实例为大家分享了js实现简单扫雷的具体代码,供大家参考,具体内容如下 实现效果: 总体思想:这个扫雷难点主要就两点:第一点就是雷的随机分布,我这里使用js动态生成了10X10的table表格,然后设定生成20个雷,然后在生成每个格子代表的数字,雷我们用9表示,因为0-8要被其他非雷格子使用,然后我们只要一格是雷区那么周围的格子都加一,这样我们的雷区就生成好了,然后玩法的编写主要难点就是在当点击数字为0时的格子时要把它周围的0区也显示出来,因此这里我们使用递归来实现 1.界面的生成 //生成界

  • 分享自己用JS做的扫雷小游戏

    引用了jQuery,节省了很多鼠标点击上的判断.界面显然都是照搬Windows的扫雷啦,详细的内容注释里都有,我就不啰嗦啦~ 先上截图~ 引用了jQuery,节省了很多鼠标点击上的判断 界面显然都是照搬Windows的扫雷啦 详细的内容注释里都有,我就不啰嗦啦~ JS部分 var mineArray, //地雷数组 lastNum, //剩余雷数 countNum, //未被揭开的方块数 inGame = 0, //游戏状态,0为结束,1为进行中,2为初始化完毕但未开始 startTime; /

随机推荐