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

开发 前端
引用了jQuery,节省了很多鼠标点击上的判断。界面显然都是照搬Windows的扫雷啦,详细的内容注释里都有,我就不啰嗦啦~

看了草根程序猿分享的JS扫雷小游戏

想起去年的时候自己也做了一个

于是也拿出来分享之

先上截图~

引用了jQuery,节省了很多鼠标点击上的判断

界面显然都是照搬Windows的扫雷啦

详细的内容注释里都有,我就不啰嗦啦~

【JS部分】

var mineArray,  //地雷数组  
    lastNum,  //剩余雷数  
    countNum,  //未被揭开的方块数  
    inGame = 0,  //游戏状态,0为结束,1为进行中,2为初始化完毕但未开始  
    startTime;  //开始时间  
    //以下操作1表示揭开一个方块,操作2表示标记一个小旗,操作3表示标记一个问号,操作4表示若某个方块周围的地雷全都标记完,则将其周围剩下的方块挖开  
$(function(){  
    $('#main').mouseup(function(e) {  
        var clicked = $(e.target),  
            id = clicked.attr('id'),  
            cX = parseInt(id.substring(1, id.indexOf('-'))),  //所点击方格的X坐标  
            cY = parseInt(id.substring(id.indexOf('-') + 1));  //所点击方格的Y坐标  
        if(inGame == 1) {  
            if(e.which == 1) {  
                if(clicked.hasClass('hidden') && !clicked.hasClass('flag')) {  
                    openBlock(cX,cY);  //左键点击未揭开且未插旗方块即执行操作1  
                } else if(!clicked.hasClass('hidden')) {  
                    openNearBlock(cX,cY);  //由于同时点击左右键实现起来比较麻烦,所以改成用点击左键实现操作4  
                }  
            } else if(e.which == 3 && clicked.hasClass('hidden')) {  //右键点击操作2,如果允许使用问号标记,则可执行操作3  
                if(clicked.hasClass('flag')) {  
                    clicked.removeClass('flag');  
                    if($('#check').attr('checked')) clicked.addClass('check');  
                    lastNum ++;  
                    countNum ++;  
                } else if(clicked.hasClass('check')) {  
                    clicked.removeClass('check');  
                } else {  
                    clicked.addClass('flag');  
                    lastNum --;  
                    countNum --;  
                }  
                $('#lastnum').text(lastNum);  
            }  
            if(lastNum == countNum) endGame(1);  //因为最后剩下的方块均为雷时应直接结束游戏,因此设置为剩余雷数和未被揭开的方块数相等的时候结束游戏  
        } else if(inGame == 2) {  
            if(e.which == 1) {  //初始化完毕后只允许点击左键开始游戏  
                openBlock(cX,cY);  
                inGame = 1;  
                var now = new Date();  
                startTime = now.getTime();  
                timer();  
            }  
        }  
    });  
    $('#main').bind('contextmenu'function(){ return false; });  //阻止默认右击事件  
});  
//初始化  
function init(x, y, mine) {  
    countNum = x * y;  
    inGame = 2;  
    lastNum = mine;  
    mineArray = new Array(y + 2);  
    $.each(mineArray, function(key) {  
        mineArray[key] = new Array(x + 2);  
    });  
    for(var i = 1; i <= y; i ++) {  
        for(var j = 1; j <= x; j ++) {  
            mineArray[i][j] = 0;  
        }  
    }  
    while(mine > 0) {  //随机布雷,-1为有雷  
        var i = Math.ceil(Math.random() * y);  
        var j = Math.ceil(Math.random() * x);  
        if(mineArray[i][j] != -1) {  
            mineArray[i][j] = -1;  
            mine --;  
        }  
    }  
    for(var i = 1; i <= y; i ++) {  //遍历地雷数组,统计每个格子四周地雷的数量  
        for(var j = 1; j <= x; j ++) {  
            if(mineArray[i][j] != -1) {  
                if(i > 1 && j > 1 && mineArray[i - 1][j - 1] == -1) mineArray[i][j] ++;  
                if(i > 1 && mineArray[i - 1][j] == -1) mineArray[i][j] ++;  
                if(i > 1 && j < x && mineArray[i - 1][j + 1] == -1) mineArray[i][j] ++;  
                if(j < x && mineArray[i][j + 1] == -1) mineArray[i][j] ++;  
                if(i < y && j < x && mineArray[i + 1][j + 1] == -1) mineArray[i][j] ++;  
                if(i < y && mineArray[i + 1][j] == -1) mineArray[i][j] ++;  
                if(i < y && j > 1 && mineArray[i + 1][j - 1] == -1) mineArray[i][j] ++;  
                if(j > 1 && mineArray[i][j - 1] == -1) mineArray[i][j] ++;  
            }  
        }  
    }  
    var block = '';  
    for(var i = 1, row = mineArray.length - 1; i < row; i ++) {  
        for(var j = 1, col = mineArray[0].length - 1; j < col; j ++) {  
            block += '<div id="b' + i + '-' + j + '" style="left:' + (j - 1) * 20 + 'px;top:' + (i - 1) * 20 + 'px;" class="hidden"></div>';  
        }  
    }  
    $('#main').html(block).width(x * 20 + 1).height(y * 20 + 1).show();  //绘图  
    $('#warning').html('');  
    $('#submenu').show();  
    $('#lastnum').text(lastNum);  
}  
//揭开方块  
function openBlock(x, y) {  
    var current = $('#b' + x + '-' + y);  
    if(mineArray[x][y] == -1) {  
        if(inGame == 1) {  //触雷时如游戏进行中,则失败结束游戏  
            current.addClass('cbomb');  
            endGame();  
        } else if(inGame == 2) {  //如游戏初始化后还未开始,则重新初始化地雷阵,再揭开此方块,以保证第一次点击不触雷  
            init(mineArray[0].length - 2, mineArray.length - 2, lastNum);  
            openBlock(x, y);  
        } else {  //游戏结束时需揭开全部方块,标记地雷位置  
            if(!current.hasClass('flag')) current.addClass('bomb');  
        }  
    } else if(mineArray[x][y] > 0) {  
        if(current.hasClass('flag')) {  //若在无雷的方块上标记了小旗,如果周围的广场执行操作4时波及到此方块,则触发失败结束游戏  
            current.addClass('wrong');  
            if(inGame) endGame();  
        } else {  
            current.html(mineArray[x][y]).addClass('num' + mineArray[x][y]).removeClass('hidden');  //显示周边的地雷数量  
            if(current.hasClass('check')) current.removeClass('check');  
            if(inGame) countNum --;  
        }  
    } else {  
        if(current.hasClass('flag')) {  //同上  
            current.addClass('wrong');  
            if(inGame) endGame();  
        } else {  
            current.removeClass('hidden');  
            if(current.hasClass('check')) current.removeClass('check');  
            if(inGame) {  //点击到周边无雷的方块时,自动揭开周围方块  
                countNum --;  
                var row = mineArray.length - 2, col = mineArray[0].length - 2;  
                if(x > 1 && y > 1 && $('#b' + (x - 1) + '-' + (y - 1)).hasClass('hidden')) openBlock(x - 1, y - 1);  
                if(x > 1 && $('#b' + (x - 1) + '-' + y).hasClass('hidden')) openBlock(x - 1, y);  
                if(x > 1 && y < col && $('#b' + (x - 1) + '-' + (y + 1)).hasClass('hidden')) openBlock(x - 1, y + 1);  
                if(y < col && $('#b' + x + '-' + (y + 1)).hasClass('hidden')) openBlock(x, y + 1);  
                if(x < row && y < col && $('#b' + (x + 1) + '-' + (y + 1)).hasClass('hidden')) openBlock(x + 1, y + 1);  
                if(x < row && $('#b' + (x + 1) + '-' + y).hasClass('hidden')) openBlock(x + 1, y);  
                if(x < row && y > 1 && $('#b' + (x + 1) + '-' + (y - 1)).hasClass('hidden')) openBlock(x + 1, y - 1);  
                if(y > 1 && $('#b' + x + '-' + (y - 1)).hasClass('hidden')) openBlock(x, y - 1);  
            }  
        }  
    }  
}  
//揭开格子邻近确认无雷的方块  
function openNearBlock(x, y) {  
    var flagNum = 0, hiddenNum = 0;  
    for(i = x - 1; i < x + 2; i ++) {  
        for(j = y - 1; j < y + 2; j ++) {  
            if(mineArray[i][j] != undefined) {  
                if($('#b' + i + '-' + j).hasClass('flag')) flagNum ++;  //统计方块周围的旗帜数和未揭开的方块数  
                if($('#b' + i + '-' + j).hasClass('hidden')) hiddenNum ++;  
            }  
        }  
    }  
    if(flagNum == mineArray[x][y] && hiddenNum > flagNum) {  //旗帜数和雷数相等且有未揭开方块且未插旗的方块时,则揭开它  
        for(i = x - 1; i < x + 2; i ++) {  
            for(j = y - 1; j < y + 2; j ++) {  
                if(mineArray[i][j] >= 0 && $('#b' + i + '-' + j).hasClass('hidden')) openBlock(i, j);  
            }  
        }  
    }  
}  
//计时  
function timer(){  
    if(inGame == 1) {  //只在游戏进行中计时  
        var now = new Date(),  
            ms = now.getTime();  
        $('#time').text(Math.ceil((ms - startTime) / 1000));  
        if(inGame == 1) setTimeout(function() { timer(); }, 500);  
    } else if(inGame == 2) {  
        $('#time').text('0');  
    }  
}  
//结束游戏  
function endGame(isWin) {  
    inGame = 0;  
    for(var i = 1, row = mineArray.length - 1; i < row; i ++) {  
        for(var j = 1, col = mineArray[0].length - 1; j < col; j ++) {  
            if(isWin) {  
                if($('#b' + i + '-' + j).hasClass('hidden') && !$('#b' + i + '-' + j).hasClass('flag')) $('#b' + i + '-' + j).addClass('flag');  
                lastNum = 0;  
                $('#lastnum').text(lastNum);  
            } else {  
                openBlock(i, j);  
            }  
        }  
    }  
    $('#warning').text(isWin ? 'You Win!' : 'You Lose!');  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.

【HTML部分】

<div id="menu"> 
    <a href="javascript:;" onclick="init(10,10,10);">初级</a> 
    <a href="javascript:;" onclick="init(16,16,40);">中级</a> 
    <a href="javascript:;" onclick="init(30,16,99);">高级</a> 
    <input type="checkbox" id="check" /><label for="check">是否使用标记(?)</label> 
</div> 
<div id="submenu"> 
    剩余雷数:<span id="lastnum"></span> 
    时间:<span id="time"></span>秒  
    <span id="warning"></span> 
</div> 
<div id="main"></div> 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

【CSS部分】

body{background:#fff;font-size:14px;}  
#submenu{display:none;}  
#warning{color:#ff0000;}  
#main{background:#ddd;border:1px solid #888;display:none;position:relative;}  
#main div{border:1px solid #888;font-weight:bold;height:19px;height:21px\9;line-height:18px;cursor:default;position:absolute;text-align:center;width:19px;width:21px\9;}  
.hidden{background:url(mine.gif) 0 0;}  
.flag{background:url(mine.gif) -19px 0;}  
.check{background:url(mine.gif) -38px 0;}  
.bomb{background:url(mine.gif) -57px 0;}  
.cbomb{background:url(mine.gif) -57px 0 #ff0000;}  
.wrong{background:url(mine.gif) -76px 0;}  
.num1{color:#0000ff;}  
.num2{color:#008000;}  
.num3{color:#ff0000;}  
.num4{color:#000080;}  
.num5{color:#800000;}  
.num6{color:#008080;}  
.num7{color:#000000;}  
.num8{color:#808080;} 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

最后是运行效果,你可以进入他的博客进行在线游戏

原文链接:http://www.cnblogs.com/barrichello/archive/2012/09/11/2679582.html

【编辑推荐】

  1. 编程赋予了我们什么样的改变
  2. JS游戏开发,让你的静态人物动起来
  3. JS游戏开发(二)让目标人物移动
  4. JavaScript制作新浪网易的评论块
  5. 从未离开过的JavaScript应用
责任编辑:张伟 来源: 巴里切罗的博客
相关推荐

2022-07-08 14:53:46

扫雷小游戏鸿蒙

2022-03-29 07:40:23

H5游戏开发扫雷游戏

2012-01-10 12:48:52

Java

2022-11-01 15:17:48

JS鸿蒙小游戏

2022-08-25 21:41:43

ArkUI鸿蒙

2022-10-28 16:20:10

JS鸿蒙小游戏

2022-02-11 14:02:09

游戏JS鸿蒙

2022-02-11 14:39:11

游戏JS鸿蒙

2011-03-15 13:19:11

jQuery

2023-10-17 10:20:53

VueReact

2020-08-20 20:30:49

C语言小游戏贪吃蛇

2018-01-22 20:35:27

微信小游戏开发

2020-12-09 11:42:18

WiFi IoT鸿蒙开发

2022-08-22 17:28:34

ArkUI鸿蒙

2022-08-04 13:55:08

拼数字小游戏鸿蒙

2022-10-31 15:22:37

JS鸿蒙小游戏

2022-02-17 20:18:27

JS鸿蒙操作系统

2021-02-23 07:01:24

js小游戏技术

2019-10-08 15:27:18

扫雷BashLinux

2012-01-18 10:53:08

iOS小游戏
点赞
收藏

51CTO技术栈公众号