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


Posted in Javascript onFebruary 17, 2016

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

先上截图~

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

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

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

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

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

详细的内容注释里都有,我就不??吕?

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!'); 
}

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>

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;}

以上所述是小编给大家分享自己用JS做的扫雷小游戏,希望对大家有所帮助。

Javascript 相关文章推荐
javaScript checkbox 全选/反选及批量删除
Apr 28 Javascript
seajs1.3.0源码解析之module依赖有序加载
Nov 07 Javascript
用jQuery获取IE9下拉框默认值问题探讨
Jul 22 Javascript
详解Javascript动态操作CSS
Dec 08 Javascript
jQuery给动态添加的元素绑定事件的方法
Mar 09 Javascript
jQuery实现切换字体大小的方法
Mar 10 Javascript
js实现简单折叠、展开菜单的方法
Aug 28 Javascript
jQuery实现的登录浮动框效果代码
Sep 26 Javascript
跟我学习javascript的arguments对象
Nov 16 Javascript
JS实现图片剪裁并预览效果
Aug 12 Javascript
原生js实现贪食蛇小游戏的思路详解
Nov 26 Javascript
浅谈vue项目,访问路径#号的问题
Aug 14 Javascript
javascript瀑布流布局实现方法详解
Feb 17 #Javascript
给angular加上动画效遇到的问题总结
Feb 17 #Javascript
基于jQuery实现的无刷新表格分页实例
Feb 17 #Javascript
jQuery实现伪分页的方法分享
Feb 17 #Javascript
jQuery simplePage+AJAX plus分页插件用法实例
Feb 17 #Javascript
DeviceOne 让你一见钟情的App快速开发平台
Feb 17 #Javascript
纯JavaScript代码实现文本比较工具
Feb 17 #Javascript
You might like
重置版战役片段
2020/04/09 魔兽争霸
windwos下使用php连接oracle数据库的过程分享
2014/05/26 PHP
PHP使用Mysql事务实例解析
2014/09/08 PHP
php使用curl下载指定大小的文件实例代码
2017/09/30 PHP
php实现socket推送技术的示例
2017/12/20 PHP
PHP的RSA加密解密方法以及开发接口使用
2018/02/11 PHP
PHP基于session.upload_progress 实现文件上传进度显示功能详解
2019/08/09 PHP
PHP7数组的底层实现示例
2019/08/25 PHP
Yii框架中用response保存cookie,用request读取cookie的原理解析
2019/09/04 PHP
JavaScript 拾碎[三] 使用className属性
2010/10/16 Javascript
jQuery Tab插件 用于在Tab中显示iframe,附源码和详细说明
2011/06/27 Javascript
js获取RadioButtonList的Value/Text及选中值等信息实现代码
2013/03/05 Javascript
你的 mixin 真的兼容 ECMAScript 5 吗?
2013/04/11 Javascript
javascript window.open打开新窗口后无法再次打开该窗口问题的解决方法
2014/04/12 Javascript
js中this用法实例详解
2015/05/05 Javascript
js基于cookie方式记住返回页面用法示例
2016/05/27 Javascript
jQuery Ztree行政地区树状展示(点击加载)
2016/11/09 Javascript
jQuery zTree树插件简单使用教程
2017/01/10 Javascript
Bootstrap的popover(弹出框)在append后弹不出(失效)
2017/02/27 Javascript
javaScript中封装的各种写法示例(推荐)
2017/07/03 Javascript
[07:59]2014DOTA2叨叨刀塔 林熊猫称被邀请赛现场盛况震撼
2014/07/21 DOTA
Python利用ElementTree模块处理XML的方法详解
2017/08/31 Python
python批量查询、汉字去重处理CSV文件
2018/05/31 Python
python清除函数占用的内存方法
2018/06/25 Python
python实现换位加密算法的示例
2018/10/14 Python
我能否用void** 指针作为参数, 使函数按引用接受一般指针
2013/02/16 面试题
介绍一下Java的事务处理
2012/12/07 面试题
安全检查验收制度
2014/01/12 职场文书
安全生产演讲稿
2014/05/09 职场文书
小学班级特色活动方案
2014/08/31 职场文书
嘉宾邀请函
2015/01/31 职场文书
学雷锋主题班会教案
2015/08/13 职场文书
运动会广播稿300字
2015/08/19 职场文书
团组织关系介绍信
2019/06/24 职场文书
标会主持词应该怎么写?
2019/08/15 职场文书
SQL Server远程连接的设置步骤(图文)
2022/03/23 SQL Server