分享自己用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 中令人困惑的变量赋值
Aug 13 Javascript
优化 JavaScript 代码的方法小结
Jul 16 Javascript
checkbox勾选判断代码分析
Jun 11 Javascript
javascript原型链继承用法实例分析
Jan 28 Javascript
JavaScript ES5标准中新增的Array方法
Jun 28 Javascript
基于Vue如何封装分页组件
Dec 16 Javascript
jQuery文字轮播特效
Feb 12 Javascript
利用js判断手机是否安装某个app的多种方案
Feb 13 Javascript
Angular.js中处理页面闪烁的方法详解
Mar 09 Javascript
vue2.0实战之使用vue-cli搭建项目(2)
Mar 27 Javascript
小程序云开发初探(小结)
Oct 24 Javascript
JavaScript执行机制详细介绍
Dec 06 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
php小技巧之过滤ascii控制字符
2014/05/14 PHP
PHP使用xpath解析XML的方法详解
2017/05/20 PHP
JS拖动技术 关于setCapture使用
2010/12/09 Javascript
js函数的延迟加载实现代码
2012/10/11 Javascript
Jquery创建一个层当鼠标移动到层上面不消失效果
2013/12/12 Javascript
jquery validate 自定义验证方法介绍 日期验证
2014/02/27 Javascript
js 验证身份证信息有效性
2014/03/28 Javascript
javascript匿名函数实例分析
2014/11/18 Javascript
微信WeixinJSBridge API使用实例
2015/05/25 Javascript
JavaScript tab选项卡插件实例代码
2016/02/23 Javascript
Angularjs 实现一个幻灯片示例代码
2016/09/08 Javascript
微信小程序云开发之数据库操作
2019/05/18 Javascript
微信JS-SDK实现微信会员卡功能(给用户微信卡包里发送会员卡)
2019/07/25 Javascript
原生js添加一个或多个类名的方法分析
2019/07/30 Javascript
Vue 实例事件简单示例
2019/09/19 Javascript
vue自定义指令实现仅支持输入数字和浮点型的示例
2019/10/30 Javascript
前端vue如何使用高德地图
2020/11/05 Javascript
关于element的表单组件整理笔记
2021/02/05 Javascript
python中pycurl库的用法实例
2014/09/30 Python
跟老齐学Python之变量和参数
2014/10/10 Python
Python的gevent框架的入门教程
2015/04/29 Python
Python sqlite3事务处理方法实例分析
2017/06/19 Python
django静态文件加载的方法
2018/05/20 Python
详解python中的json和字典dict
2018/06/22 Python
python实战教程之自动扫雷
2018/07/13 Python
python 遍历列表提取下标和值的实例
2018/12/25 Python
如何实现Django Rest framework版本控制
2019/07/25 Python
浅谈Python中re.match()和re.search()的使用及区别
2020/04/14 Python
GoDaddy英国:全球排名第一的域名注册商
2018/06/08 全球购物
美国最大的在线生存商店:Survival Frog
2020/12/13 全球购物
一套比较完整的软件测试人员面试题
2012/05/13 面试题
解释i节点在文件系统中的作用
2013/11/26 面试题
花卉与景观设计系大学生求职信
2013/10/01 职场文书
工作会议欢迎词
2014/01/16 职场文书
JavaScript实现登录窗体
2021/06/22 Javascript
浅谈MySql整型索引和字符串索引失效或隐式转换问题
2021/11/20 MySQL