您的位置:首页 > Web前端 > JavaScript

纯js实现扫雷小游戏

2018-10-07 10:24 429 查看

项目地址:https://github.com/zhuyuzhu/sweep-mine

git地址:https://github.com/zhuyuzhu/sweep-mine.git

(1)html代码:

[code] <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="./sweepMine.css">
<title>JavaScript实现web扫雷小游戏</title>
</head>
<body>
<div class="wrapper">
<div class="btn" id="startBtn"></div>
<div class="box" id="box"></div>
<div class="flagBox" id="flagBox">
当前还有地雷个数:
<span id="score">10</span>
</div>
<div class="alertBox" id="alertBox">
<div class="alertImg" id="alertImg">
<div class="close" id="close"></div>
</div>
</div>
</div>
<script src="./sweepMine.js"></script>
</body>
</html>

(2)css代码:

[code]*{
padding: 0px;
margin: 0px;
}
.wrapper {
width: 100%;
height: 700px;
position: fixed;
top: 0px;
left: 0px;
background-image: url('./pictures/background.jpg');
background-size: 100% 100%;
}
.btn {
height: 70px;
width: 170px;
position: absolute;
left: 50px;
background-image: url('./pictures/startGame.jpg');
background-size: 100% 100%;
cursor: pointer;
}
.box {
height: 500px;
width: 500px;
transform: perspective(800px) rotateX(45deg);
margin: 20px auto;
border: 1px solid #b25f27;
box-shadow: 5px 5px 5px rgba(0,0,0,0.3);
/* display: none; */
}
.flagBox{
position: absolute;
top: 50px;
left: 50%;
width: 220px;
height:50px;
margin-left: -100px;

font-size: 20px;
font-weight: bolder;
/* display: none; */
color: #fff;
}
.alertBox {
display: none;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
background-color: rgba(0,0,0,0.2);

}
.alertImg {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
width: 600px;
height: 400px;
/* background-image: url('./pictures/success.jpg'); */
background-size: 100% 100%;
margin: auto;
border-radius: 20px;
}
.close {
position: absolute;
top: 0px;
right: 0px;
width: 40px;
height: 40px;
background-image: url('./pictures/close.jpg');
background-size: 100% 100%;
cursor: pointer;
border-radius: 50%;
}
.block {
float: left;
width: 49px;
height: 49px;
border-right: 1px solid #b25f27;
border-bottom: 1px solid #b25f27;
box-shadow: 0 0 4px #333 inset;
background-image: url('./pictures/grassland.jpg');
}
.show {
background-image: url('./pictures/mine.jpg');
background-size: 100% 100%;
}
.number{
background: #ecd0a1;
font-size: 18px;
font-weight: bold;
line-height: 49px;
text-align: center;
}
.flag{
background-image: url('./pictures/flag.jpg');
background-size: 100% 100%;
}

js代码:

[code]// (1)当点击开始游戏后会动态生成10 * 10 的小格子
// (2)当点击某个小格子的时候,如果不是雷,会显示周围8个格子的雷数量
//   如果8个格子都不是雷,那么就会分别扩散
// 左键点击的时候,吐过是雷,就gameover,且所有的雷都显示出来
// (3)当右键点击的时候,是标记或取消标记
// (4)左键或右键无效的情况

var startBtn = document.getElementById('startBtn');
var box = document.getElementById('box');
var flagBox = document.getElementById('flagBox');
var alertBox = document.getElementById('alertBox');
var alertImg = document.getElementById('alertImg');
var close = document.getElementById('close');
var score = document.getElementById('score');
var minesNum;
var mineOver;
var block;
var mineMap = [];
var flagNum = 0;//插的旗子的个数
// 游戏是失败的时候,背景音乐,先进行加载
var gameoverAudio = document.createElement('audio');
gameoverAudio.src = './Gameover.mp3';
window.onload = function () {

document.body.appendChild(gameoverAudio);
}
//当点击开始的时候,雷盘出现
bindEvent();
function bindEvent() {
startBtn.onclick = function () {
box.innerHTML = ''; // 清除旧的雷盘
box.style.display = 'block';
flagBox.style.display = 'block';
init();

}
//取消右键菜单的默认事件
box.oncontextmenu = function () {
return false;
}
//鼠标点击事件
box.onmousedown = function (event) {
var event = event || window.event;//事件
if (box.style.display == 'block'){
if (event.which == 1) {// 如果是左键
leftClick(event.target); //事件源对象
} else if (event.which == 3) {// 如果是右键
rightClick(event.target);
}
}
}

close.onclick = function () {
alertBox.style.display = 'none';
}
}
function init() {
minesNum = 10; //雷的总数
mineOver = 10; //雷的剩余数
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
var con = document.createElement('div');
con.classList.add('block'); //每个小格的共同样式
con.setAttribute('id', i + '-' + j);//每个小格的值样式
box.appendChild(con);
mineMap.push({ mine: false });//每一个小格都添加一个对象,标记是否有雷
}
}
block = document.getElementsByClassName('block'); //获得100个小格子的dom元素
while (minesNum) { //其中有10个是雷
var mineIndex = Math.floor(Math.random() * 100);//随机生成一个(0 - 100)的数
if (mineMap[mineIndex].mine === false) {
block[mineIndex].classList.add('isMine'); //把随机生成的位置添加一个雷
mineMap[mineIndex].mine = true;
minesNum--;                              //剩余雷数减一
}

}
}
//左键事件
function leftClick(dom) {
var isMine = document.getElementsByClassName('isMine');

if (dom && dom.classList.contains('isMine')) { //classList.contains(class),判断指定的类名是否存在,如果点到雷
console.log('gameover');  // 弹出游戏结束的图片
for (var i = 0; i < isMine.length; i++) { //所有的雷都显示出来
isMine[i].classList.remove('flag');//将点开的格子上的旗子清除掉(如果有旗子的话)
isMine[i].classList.add('show');

}
// gameoverAudio.currentTime = 0;
// gameoverAudio.play(); // 播放gameover的音效
// setTimeout(function(){ // 取该音乐的前5s播放
//     gameoverAudio.pause();
// },2500);
setTimeout(function () {
alertBox.style.display = 'block';
alertImg.style.backgroundImage = "url('./pictures/gameOver.jpg')";
}, 500);
} else {
var n = 0; // 周围雷的个数
var posArr = dom.getAttribute('id').split('-'); //将字符串拆成数组
var posX = Number(posArr[0]);
var posY = Number(posArr[1]);

dom.classList.remove('flag');//将点开的格子上的旗子清除掉(如果有旗子的话)
dom.classList.add('number'); //添加一个number样式
var flags = document.getElementsByClassName('flag');

score.innerHTML = 10-flags.length;
// 遍历周围8个格子(如果是格子的话)
for (var i = posX - 1; i <= posX + 1; i++) {
for (var j = posY - 1; j <= posY + 1; j++) {
var aroundBox = document.getElementById(i + '-' + j);
if (aroundBox && aroundBox.classList.contains('isMine')) { //如果是带有雷的class
n++;
}
}
}
dom && (dom.innerHTML = n);//如果是格子的话,格子内的内容是n
if (n == 0) {
// 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 isMine = document.getElementsByClassName('isMine');
var flags = document.getElementsByClassName('flag');//插旗子的dom元素
var allMinesFlag = true;
//如果右键点击带有数的格子,注意:带有数字的都是被点开的。
//没有被点开的格子,还没有分配数字。
if (dom.classList.contains('number')) {
return
}
dom.classList.toggle('flag');// toggle(class, true|false)在元素中切换类名

score.innerHTML = 10 - flags.length; //10 - 插旗子的个数
for(var i=0; i<isMine.length; i++){
allMinesFlag = allMinesFlag && isMine[i].classList.contains('flag')
}
console.log(allMinesFlag);
if(allMinesFlag && (10-flags.length)==0){
console.log(1);
setTimeout(function () {
alertBox.style.display = 'block';
alertImg.style.backgroundImage = "url('./pictures/success.jpg')";
}, 500);
}
}

 运行结果:

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: