HTML,css,js自制简易版扫雷
在1.0版本我完成的功能有:
- 简单模式的雷盘创建(10*10)
- 随机生成雷
- 显示周围雷数的效果
- 左键点击空白处,会将附近非雷且未打开的区域打开并显示数字
- 右键可以进行标记与取消标记(使用胡萝卜图片进行标记)
- 左键点到雷后,会立刻出现雷(月饼)的图案,过1秒出现雷,且有爆炸效果,在3.5秒过后显示游戏结束
下面是部分代码的制作
制作css部分
关于具体布局我就不展示了,只把一会js需要用到的代码部分,即(覆盖层,雷层,数字层,爆炸层)的样式显示出来
覆盖层样式
.block {
float: left;
width: 49px;
height: 49px;
border-right: 1px solid #d85f1a;
border-bottom: 1px solid #d85f1a;
box-shadow: 0 0 4px #333 inset;
background: url(../img/15.jpg);
background-size: 100% 100%;
}
这是覆盖层效果
数字层样式
.number {
background: #f6eeec;
font-size: 18px;
font-weight: bold;
line-height: 49px;
text-align: center;
}
雷层样式
.show {
background: url(../img/13.jpg);
background-size: 100% 100%;
}
爆炸层样式
.boom {
background: url(../img/bool.gif);
background-size: 100% 100%;
}
游戏开始和结束部分
js部分
创建雷盘部分
function init() {
leinum = 10;//设置雷数为10个
for (var i = 0; i < 10; i++) { //10可以用变量改,在创建选择模式时
for (var j = 0; j < 10; j++) {
var con = document.createElement('div');
con.classList.add("block");
con.setAttribute('id', i + "-" + j); //给生成的格子创建id
box.appendChild(con);
leiMap.push({ //每个雷格是否有雷 默认为false
mine: false
});
}
}
blocks = document.getElementsByClassName('block'); //获取100个格子的dom元素
while (leinum) {
var leiindex = Math.floor(Math.random() * 100); //随机生成0-100范围内的数
if (leiMap[leiindex].mine === false) {
blocks[leiindex].classList.add('isMine'); //随机生辰一个雷
leiMap[leiindex].mine = true;//代表有雷
leinum--;
}
}
}
因为扫雷这个游戏是用鼠标左键和右键进行的,所以我将游戏就分为了左键点击事件和右点击事件来设置
左点击事件
function leftClick(dom) {
var isMine = document.getElementsByClassName('isMine'); //获取带有 isMine的类名,代表是雷
if (dom && dom.classList.contains('isMine')) { //判断点击的是否是雷
dom.classList.add('show'); //点击的地方雷出现
for (let i = 0; i < isMine.length; i++) {
isMine[i].classList.add('show'); //所有的雷出现
setTimeout(function() {
isMine[i].classList.add('boom'); //1秒后执行爆炸样式
}, 1000);
}
// 结束弹框
setTimeout(function() {
alterbox.style.display = 'block'; //代表游戏结束
}, 3500)
} else {
var n = 0; //周围雷的个数
var posArr = dom.getAttribute("id").split('-'); //将字符串拆成数组
var posX = Number(posArr[0]);
var posY = Number(posArr[1]);
dom.classList.remove('flag'); //如果有标记则移除标记
var flags = document.getElementsByClassName('flag');
score.innerHTML = 10 - flags.length; //在点开不是雷的地方且有标记时,更新上方数字
dom.classList.add('number'); //添加数字样式
for (var i = posX - 1; i <= posX + 1; i++) {
for (var j = posY - 1; j <= posY + 1; j++) {
var arroundBox = document.getElementById(i + '-' + j);
if (arroundBox && arroundBox.classList.contains('isMine')) {
n++;
}
}
}
dom && (dom.innerHTML = n); //给棋盘添加上数字
if (n == 0) {
// 在 点击的这个盒子的周围8个盒子
for (var i = posX - 1; i <= posX + 1; i++) {
for (var j = posY - 1; j <= posY + 1; j++) {
var nearBox = document.getElementById(i + '-' + j);
if (nearBox && nearBox != 0) {
// 如果附近这个格子不是0,并且没有被点击,那么系统自动打开,并添加一个checked类 ,但到数字不是时就会停止
if (!nearBox.classList.contains('checked')) {
nearBox.classList.add('checked');
leftClick(nearBox);
//再次调用点击事件,进行递归,但这次的递归是判断是雷不是雷,而不是0
}
}
}
}
}
};
}
右手点击事件
function rightClick(dom) {
var flags = document.getElementsByClassName('flag');
var allMinesFlag = true;
var isMine = document.getElementsByClassName('isMine');
if (dom.classList.contains('number')) { //如果点击的是数字,就不能进行标记
return
}
dom.classList.toggle('flag'); //给没有标记的格子加上标记,有标记的取消标记
score.innerHTML = 10 - flags.length; //标记的数
//判断是否所有的雷都插上了旗子
for (var i = 0; i < isMine.length; i++) {
allMinesFlag = allMinesFlag && isMine[i].classList.contains('flag');
//只有有一个没有被标记,那么 allMinesFlag都会为false,就不能进行下面的判断
}
if (allMinesFlag && (10 - flags.length) == 0) {
for (let i = 0; i < isMine.length; i++) {
isMine[i].classList.add('show');
isMine[i].classList.remove('flag');
setTimeout(function() {
isMine[i].classList.add('boom');
}, 1500);
}
setTimeout(function() {
endtext.innerHTML = 'Game Won';
alterbox.style.display = 'block';
}, 3000)
}
}
相关链接:扫雷源码