HTML代码

<title>
扫雷
</title>
<!-- ondragstart:防拖拽生成新页面 oncontextmenu:屏蔽右键菜单-->
<body ondragstart='return false' oncontextmenu='self.event.returnValue=false'>
<div id='bar'>
<span class='bar'>
剩余雷数:
<label id='count'>
0
</label>
</span>
<span class='bar'>
计时:
<label id='time'>
0
</label>
s
</span>
</div>
<table id='grid'>
</table>

CSS代码

#bar {
text-align: center;
margin-bottom: 20px;
} .bar {
height: 25px;
width: 150px;
line-height: 25px;
display: inline-block;
border: solid 1px #000;
margin-left: 20px;
margin-right: 20px;
} #grid {
margin: auto;
} .blocks {
width: 30px;
height: 30px;
line-height: 30px;
display: block;
text-align: center;
border: solid 1px #000;
user-select: none;
cursor: pointer;
} .blocks:hover {
background: #0af;
}

JS代码

var row = 10; //行数
var col = 10; //列数
var maxCount = 10; //最大地雷数量
var isFirstOpen = true; //第一次打开方格
var grid = init_grid(); //初始化
var count = document.getElementById('count'); //剩余地雷数
count.innerHTML = maxCount; //初始化剩余雷数
var time = document.getElementById('time'); //计时器
var timer = setInterval(function() {
let seconds = (parseFloat(time.innerHTML) + 0.1).toFixed(1); //保留一位小数
time.innerHTML = seconds;
},
100) //定时器 100ms执行一次
//初始化矩阵 (row-行数 col-列数)
function init_grid() { //生成矩阵html <tr>--行标签 <td>--列标签
let gridHtml = '';
for (let i = 0; i < row; i++) {
gridHtml += '<tr>'
for (let j = 0; j < col; j++) {
gridHtml += '<td><span class="blocks" onmousedown="block_click(' + i + ',' + j + ',event)"></span></td>';
}
gridHtml += '<tr>'
}
//写入html
document.getElementById('grid').innerHTML = gridHtml; //返回矩阵二维数组
let blocks = document.getElementsByClassName('blocks');
let grid = new Array();
for (let i = 0; i < blocks.length; i++) {
if (i % col === 0) {
grid.push(new Array());
}
//初始化计雷数
blocks[i].count = 0;
grid[parseInt(i / col)].push(blocks[i]);
}
return grid;
} //方格点击事件 _i:坐标i _j:坐标j e:鼠标事件
function block_click(_i, _j, e) { //跳过已打开的方格
if (grid[_i][_j].isOpen) {
return;
} //鼠标左键打开方格
if (e.button === 0) { //第一次打开
if (isFirstOpen) { isFirstOpen = false;
let count = 0; //当前地雷数
//生成地雷
while (count < maxCount) { //生成随机坐标
let ri = Math.floor(Math.random() * row);
let rj = Math.floor(Math.random() * col); //坐标不等于第一次点击方格的坐标 && 非雷方格
if (! (ri === _i && rj === _j) && !grid[ri][rj].isMine) {
grid[ri][rj].isMine = true; //自定义属性isMine代表方格为地雷
count++; //当前地雷数+1
//更新九宫格内非雷方格的计雷数
for (let i = ri - 1; i < ri + 2; i++) {
for (let j = rj - 1; j < rj + 2; j++) {
//判断坐标防越界
if (i > -1 && j > -1 && i < row && j < col) {
//计雷数+1
grid[i][j].count++;
}
}
}
}
}
} //执行打开方格函数
block_open(_i, _j); //打开方格函数
function block_open(_i, _j) { let block = grid[_i][_j];
op(block); //设定打开方格的状态与样式
function op(block) {
block.isOpen = true; //isOpen为自定义属性,设置为true代表已打开
block.style.background = '#ccc'; //将背景设置为灰色
block.style.cursor = 'default'; //将鼠标停留样式设置为默认
} if (block.isMine) {
//踩雷
block.innerHTML = '雷'; //显示为 '雷'
//遍历矩阵打开所有的地雷方格
for (let i = 0; i < row; i++) {
for (let j = 0; j < col; j++) {
//找到地雷
block = grid[i][j];
if (!block.isOpen && block.isMine) {
op(block); //设置打开状态和样式
block.innerHTML = '雷'; //显示为 '雷'
}
}
}
clearInterval(timer); //游戏结束停止计时,清除定时器
//提示游戏结束
alert("游戏结束");
} else if (block.count === 0) {
//打开计雷数为0的方格
//遍历九宫格内的方格
for (let i = _i - 1; i < _i + 2; i++) {
for (let j = _j - 1; j < _j + 2; j++) {
//判断是否越界&&跳过已打开的方格&&非雷
if (i > -1 && j > -1 && i < row && j < col && !grid[i][j].isOpen && !grid[i][j].ismine) {
//递归打开方格函数
block_open(i, j);
}
}
}
} else {
//打开计雷数不为0的方格
block.innerHTML = block.count; //显示计雷数
} }
}
//鼠标右键标记方格
else if (e.button === 2) { let block = grid[_i][_j];
if (block.innerHTML !== '▲') {
block.innerHTML = '▲';
} else {
block.innerHTML = '';
}
} //遍历矩阵
let isWin = true;
count.innerHTML = maxCount; //重置剩余地雷数
for (let i = 0; i < row; i++) {
for (let j = 0; j < col; j++) {
let block = grid[i][j]; //找到标记
if (block.innerHTML === '▲') {
count.innerHTML = parseInt(count.innerHTML) - 1; //剩余地雷数-1
} //判断游戏胜利条件(所有的非雷方格已打开)
if (!block.isMine && !block.isOpen) {
//如果有未打开的非雷方块 条件不成立
isWin = false;
}
}
}
if (isWin) {
clearInterval(timer); //游戏胜利结束计时,清除定时器
alert("游戏胜利");
}
}

JS扫雷小游戏的更多相关文章

  1. Angular4 扫雷小游戏

    扫雷小游戏,可以升级过关,难度随关卡增加.但是有很明显的bug,以后有时间会继续优化! HTML: <div class="mainContent"> <div ...

  2. pixi.js 微信小游戏 入手

    pixi是什么?一款h5游戏引擎 优点:简单简洁性能第一 缺点:大多数用的国产三大引擎,pixi资料少,工具少, 为什么学,装逼 用pixi开发小游戏行吗? 行.但要简单处理下 下载官网上的 weap ...

  3. 扫雷小游戏PyQt5开发【附源代码】

    也没啥可介绍哒,扫雷大家都玩过. 雷的分布算法也很简单,就是在雷地图(map:二维数组)中,随机放雷,然后这个雷的8个方位(上下左右.四个对角)的数字(非雷的标记.加一后不为雷的标记)都加一. 如何判 ...

  4. JS写小游戏(一):游戏框架

    前言 前一阵发现一个不错的网站,都是一些用html5+css+js写的小游戏,于是打算学习一番,写下这个系列博客主要是为了加深理解,当然也有一些个人感悟,如果英文好可以直接Click Here. 概述 ...

  5. web版扫雷小游戏(一)

    作为一名程序猿,平时的爱好也不多,说起游戏,我不太喜欢大型的网游,因为太耗时间,偶尔玩玩经典的单机小游戏,比如windows下自带的游戏扫雷(秀一下,高级下最高纪录110s). 现阶段正在致力于web ...

  6. three.js 微信小游戏

    最近在 https://classroom.udacity.com/courses/cs291 学习了一些 3D 引擎和 three.js 的知识 把 three.js 弄到微信小游戏里,先随便跑一跑 ...

  7. js消除小游戏(极简版)

    js小游戏极简版 (1) 基础布局 <div class = "box"> <p></p> <div class="div&qu ...

  8. C++扫雷小游戏(基于CMD命令行)

    这个小游戏是笔者在大一C语言课程设计的时候写的,基于命令行,为了显得漂亮一些,特别加上了彩色特效~~~ 注意:Win10系统须将命令行调为旧版命令行,否则有可能会显示乱码! 代码示例: #includ ...

  9. 无聊的周末用Java写个扫雷小游戏

    周末无聊,用Java写了一个扫雷程序,说起来,这个应该是在学校的时候,写会比较好玩,毕竟自己实现一个小游戏,还是比较好玩的.说实话,扫雷程序里面核心的东西,只有点击的时候,去触发更新数据这一步. Sw ...

随机推荐

  1. 消息队列(MQ)

    什么是消息队列 消息队列,即MQ,Message Queue. 消息队列是典型的:生产者.消费者模型.生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息.因为消息的生产和消费都是异步的,而且 ...

  2. 用JAVA打印出棱形

    public class Test { public static void main(String[] args) { //输入行数 print(5); } public static void p ...

  3. Pandas Series 与 DataFrame 数据创建

    >>> import pandas as pd >>> import numpy as np >>> print(np.__version__), ...

  4. Docker笔记(三):Docker安装与配置

    原文地址:http://blog.jboost.cn/2019/07/14/docker-3.html Docker分为Docker CE社区免费版与Docker EE企业收费版.Docker EE主 ...

  5. 《Predict Anchor Links across Social Networks via an Embedding Approach》阅读笔记

    基本信息 文献:Predict Anchor Links across Social Networks via an Embedding Approach 时间:2016 期刊:IJCAI 引言 预测 ...

  6. 第二章 Session会话管理

    采用网址重写的缺点: 在有些Web浏览器中,URL限制为2000个字符. 仅当有链接要插入值时,值才能转换成后面的资源.此外,要把值添加到静态页面的链接中,可不是一件容易的事情. 网址重写必须在服务器 ...

  7. MyBatis 接口多参数的处理方法

    From<MyBatis从入门到精通> 1.接口类中增加的方法: /* 2.7 多个接口参数的用法 多个参数时,可以选取的方案有:使用Map类型或者使用@Param注解 使用Map类型作为 ...

  8. js深入之call、apply和bind

    一. call和apply 1. 代码完整实现 Function.prototype.mycall = function (context, ...argus) { if (typeof this ! ...

  9. Spring的注解问题

    Annotation(注解)概述 从JDK5.0开始, Java增加了对元数据(MetaData)的支持,也就是 Annotation(注解). Annotation其实就是代码里的特殊标记,它用于替 ...

  10. 关于python3与python2同时存在情况下导入pyqt失败解决记录

    最近感觉tkinter功能还是比较不适合新手做出高大上的界面,故开始使用pyqt,通过pip安装好了之后,利用qt设计师设计好界面之后,cmd运行之,报错提示没有找到pyqt5模块,IDE运行能正常加 ...