如何用JS写个完整的扫雷游戏,过程是什么

Admin 2022-10-31 群英技术资讯 483 次浏览

这篇文章主要介绍了“如何用JS写个完整的扫雷游戏,过程是什么”相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何用JS写个完整的扫雷游戏,过程是什么文章都会有所收获,下面我们一起来看看吧。

前言

扫雷大家都玩过,今天我们就是用JavaScript来打造扫雷游戏。废话不多说,直接看下效果;

上图是失败后的结果。

一、思路分析

我们新建一个首页,在首页放置一个点击开始游戏的按钮,动态生成100个小格,即100div;然后通过点击div进行扫雷操作,然后扫雷成功或者失败显示对应的结果;

二、静态页面搭建

2.1 结构层

<body>
    <div class="wrapper">
        <div class="btn" id="btn"></div>  <!-- 开始游戏按钮-->
        <div class="box" id="box"></div>  <!-- 存放小雷的div-->
        <div class="flagBox" id="flagBox"> <!-- 游戏结束才显示的当前雷数的div-->
            当前剩余雷数:
            <span id="score">10</span>
        </div>
        <div class="alertBox" id="alertBox">  <!-- Game over弹出的框(窗口)-->
            <div class="alertImg" id="alertImg">
                <div class="close" id="close"></div>
            </div>
        </div>
    </div>
</body>

2.2 样式层

清楚默认边距

*{
    margin:0;
    padding:0;
}

页面最大div

.wrapper {
    width:100%;
    height:1000px;
    position: fixed;
    top:0;
    left:0;
    background-image: url('img/bg.jpg');
    background-size: 100% 100%;
}

效果如下:

开始游戏按钮

.btn{
    height:140px;
    width:170px;
    position:absolute;
    left:50px;
    background-image: url('img/startGame.png');
    background-size: 100% 100%;
    cursor: pointer;
}

储存雷的大div

.box{
    height:500px;
    width:500px;
    transform: perspective(800px) rotateX(45deg);
    margin:20px auto;
    border-top:1px solid #B25F27;
    border-left:1px solid #B25F27;
    box-shadow:  5px 5px 5px rgba(0,0,0,0.3);
    display:none; /* 先设置为none,开始游戏后显示block */ 
}

每一个方块的小div(一共100个)

.block{
    width:49px;
    height:49px;
    border-right:1px solid #B25F27;
    border-bottom:1px solid #B25F27;
    box-shadow: 0 0 4px #333 inset;
    background-image: url('img/cao.jpg');
    float: left;
}

当前所剩雷数

.flagBox{
    position:absolute;
    top:50px;
    left:50%;
    width:200px;
    height:50px;
    margin-left:-100px;
    color:#333;
    font-size:20px;
    font-weight: bolder;
    display:none; /* 先设置为none,开始游戏后显示block */ 
}

Game Over

.alertBox{
    display:none; /* 先设置为none,开始结束显示block */ 
    position:absolute;
    width:100%;
    height:100%;
    left:0;
    top:0;
    background-color: rgba(0,0,0,0.2);
}

游戏结束弹出窗口右上角的X

.close{
    position:absolute;
    right:0;
    top:0;
    height:40px;
    width:40px;
    background-image: url('img/closeBtn.png');
    background-size: 100% 100%;
    cursor: pointer;
​​​​​​​}

三、js页面交互

3.1 获取元素及变量初始化

var startBtn = document.getElementById('btn');
var box = document.getElementById('box');
var flagBox = document.getElementById('flagBox');
var alertBox = document.getElementById('alertBox');
var alertImg = document.getElementById('alertImg');
var closeBtn = document.getElementById('close');
var score = document.getElementById('score');
// 先声明变量,但是不初始化
var minesNum;
var mineOver;
var block;
var mineMap = [];
var startGameBool = true;

3.2 10个雷的初始化设置

function init() {
    minesNum = 10;
    mineOver = 10;
    score.innerHTML = mineOver;
    
    for (var i = 0; i < 10; i++) { // 双层循环 10 * 10 个div
        for (var j = 0; j < 10; j++) {
            var con = document.createElement('div');
            con.classList.add('block'); // 给创建出来的div添加类名 block 
            con.setAttribute('id', i + '-' + j);
            box.appendChild(con);
            mineMap.push({ mine: 0 });
        }
    }
    block = document.getElementsByClassName('block');
    while (minesNum) { // 创建一个10次的循环,即设置10个雷
        var mineIndex = Math.floor(Math.random() * 100);
        if (mineMap[mineIndex].mine === 0) {
            mineMap[mineIndex].mine = 1;
            block[mineIndex].classList.add('isLei'); // 10个雷有小div的block类属性,还有自己的属性,isLei
            minesNum--;
        }
    }
}

3.3 游戏开始事件封装

function bindEvent() {
    startBtn.onclick = function () { // 开始按钮点击事件
        if(startGameBool){
            box.style.display = 'block';
            flagBox.style.display = 'block';
            init();
            startGameBool = false;
        }
    }
    box.oncontextmenu = function () {
        return false;
    }
    box.onmousedown = function (e) { // 小div鼠标按下事件封装
        var event = e.target;
        if (e.which == 1) { //Netscape/Firefox/Opera中不支持 window.event.keyCode,需要用event.which代替
            leftClick(event);
        } else if (e.which == 3) {
            rightClick(event);
        }
    }
    closeBtn.onclick = function () { // 游戏结束,弹出game over窗口的关闭按钮事件封装
        alertBox.style.display = 'none';
        flagBox.style.display = 'none';
        box.style.display = 'none';
        box.innerHTML = '';
        startGameBool = true;
    }
}

3.4 核心事件函数封装

leftClick 没有雷 --> 显示数字(代表以当前小格为中心周围8个格的雷数)扩散(当前周围八个格没有雷) 有雷 --> game Over

function leftClick(dom) {
    if(dom.classList.contains('flag')){
        return;
    }
    var isLei = document.getElementsByClassName('isLei'); // 获得前面的10个雷的div
    if (dom && dom.classList.contains('isLei')) { // 判断是不是雷块
        for (var i = 0; i < isLei.length; i++) {
            isLei[i].classList.add('show'); // 显示地雷背景图
        }
        setTimeout(function () {
            alertBox.style.display = 'block';
            alertImg.style.backgroundImage = 'url("img/over.jpg")';  // 上面显示雷,标志游戏结束
        }, 800)
    } else { // 否则继续扫雷
        var n = 0;
        var posArr = dom && dom.getAttribute('id').split('-');
        var posX = posArr && +posArr[0];
        var posY = posArr && +posArr[1];
        dom && dom.classList.add('num');
        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('isLei')) {
                    n++;
                }
            }
        }
        dom && (dom.innerHTML = n);
        if (n == 0) {
            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.length != 0) {
                        if (!nearBox.classList.contains('check')) {
                            nearBox.classList.add('check');
                            leftClick(nearBox);
                        }
                    }
                }
            }
        }
    }
}

rightClick 没有标记并且没有数字 --> 进行标记;

有标记 --> 取消标记 --> 标记是否正确,10个都正确标记,提示成功;

如果已经出现,则点击无效果;

function rightClick(dom){
    if(dom.classList.contains('num')){ // 如果已经出现,则点击无效果
        return;
    }
    dom.classList.toggle('flag'); // 在元素中切换类名,切换为flag类名,显示红旗背景图;此处的雷被扫除了
    if(dom.classList.contains('isLei') && dom.classList.contains('flag')){
        mineOver --; // 雷数减一
    }
    if(dom.classList.contains('isLei') && !dom.classList.contains('flag')){
        mineOver ++;
    }

    score.innerHTML = mineOver;
    if(mineOver == 0){ // 扫完雷,标志雷数量为0
        alertBox.style.display = 'block';
        alertImg.style.backgroundImage = 'url("img/success.png")'; // 游戏胜利
    }
}

3.5 游戏开始

bindEvent()

四、总结



上述内容具有一定的借鉴价值,感兴趣的朋友可以参考,希望能对大家有帮助,想要了解更多"如何用JS写个完整的扫雷游戏,过程是什么"的内容,大家可以关注群英网络的其它相关文章。 群英智防CDN,智能加速解决方案
标签: js扫雷游戏

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

猜你喜欢

成为群英会员,开启智能安全云计算之旅

立即注册
专业资深工程师驻守
7X24小时快速响应
一站式无忧技术支持
免费备案服务
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
在线客服
微信公众号
返回顶部
返回顶部 返回顶部
在线客服
在线客服