分享自己用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 更新 JavaScript 数组的 uniq 方法
Jan 23 Javascript
JavaScript中valueOf函数与toString方法深入理解
Dec 02 Javascript
javascript dom追加内容实现示例
Sep 21 Javascript
JavaScript设置首页和收藏页面的小例子
Nov 11 Javascript
js获取判断上传文件后缀名的示例代码
Feb 19 Javascript
引用其它js时如何同时处理多个window.onload事件
Sep 02 Javascript
javascript实现列表滚动的方法
Jul 30 Javascript
项目实践一图片上传之form表单还是base64前端图片压缩(前端图片压缩)
Jul 28 Javascript
web.js.字符串与正则表达式操作
May 13 Javascript
JS之if语句对接事件动作逻辑(详解)
Jun 28 Javascript
node实现登录图片验证码的示例代码
Apr 20 Javascript
解决elementui表格操作列自适应列宽
Dec 28 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重定向的三种方法分享
2012/02/22 PHP
PHP写的加密函数,支持私人密钥(详细介绍)
2013/06/09 PHP
php实现RSA加密类实例
2015/03/26 PHP
织梦sitemap地图实时推送给百度的教程
2015/08/03 PHP
js获取单选框或复选框值及操作
2012/12/18 Javascript
js中的push和join方法使用介绍
2013/10/08 Javascript
node.js中的socket.io入门实例
2014/04/26 Javascript
js中使用replace方法完成某个字符的转换
2014/08/20 Javascript
javascript实现单击和双击并存的方法
2014/12/13 Javascript
深入理解JavaScript的React框架的原理
2015/07/02 Javascript
JavaScript模块化开发之SeaJS
2015/12/13 Javascript
jQuery+css3实现转动的正方形效果(附demo源码下载)
2016/01/27 Javascript
[原创]Bootstrap 中下拉菜单修改成鼠标悬停直接显示
2016/04/14 Javascript
JavaScript中的操作符类型转换示例总结
2016/05/30 Javascript
利用Node.js制作爬取大众点评的爬虫
2016/09/22 Javascript
利用CSS、JavaScript及Ajax实现图片预加载的方法
2016/11/29 Javascript
ionic2 tabs使用 Modal底部tab弹出框
2016/12/30 Javascript
react.js 获取真实的DOM节点实例(必看)
2017/04/17 Javascript
JQuery EasyUI 结合ztrIee的后台页面开发实例
2017/09/01 jQuery
vue动态路由配置及路由传参的方式
2018/05/23 Javascript
利用原生JS实现data方法示例代码
2019/05/28 Javascript
使用JS实现动态时钟
2020/03/12 Javascript
[43:32]Winstrike vs VGJ.S 2018国际邀请赛淘汰赛BO3 第一场 8.23
2018/08/24 DOTA
python OpenCV学习笔记之绘制直方图的方法
2018/02/08 Python
python 定时修改数据库的示例代码
2018/04/08 Python
python 的 openpyxl模块 读取 Excel文件的方法
2019/09/09 Python
使用Python刷淘宝喵币(低阶入门版)
2019/10/30 Python
python中adb有什么功能
2020/06/07 Python
美国著名的团购网站:Woot
2016/08/02 全球购物
Does C# support multiple inheritance? (C#支持多重继承吗)
2012/01/04 面试题
医学专业毕业生个人求职信
2013/12/25 职场文书
小溪流的歌教学反思
2014/02/13 职场文书
态度决定一切演讲稿
2014/05/20 职场文书
职工培训工作总结
2015/08/10 职场文书
SpringCloud的JPA连接PostgreSql的教程
2021/06/26 Java/Android
Android存储中最基本的文件存储方式
2022/04/30 Java/Android