现在位置首页 / 项目实战 /正文

jquery版网页扫雷游戏源代码详细分析及Demo下载2

作者: IT小兵 | 2014年5月19日| 热度:℃ | 评论: |参与:

前几天分享了jquery web版扫雷的demo,分析了开发思路、算法和部分详细代码。

今天继续发布和分析源代码:键盘事件、鼠标事件。

参考:

预览:扫雷(Jquery + html)

http://bbbzd.com/code/bomb/  


[jquery版网页扫雷游戏源代码分析及Demo下载]

[jquery版网页扫雷游戏源代码详细分析及Demo下载2]



【4】 左键事件:如果div是雷,直接爆炸,gameOver;如果是数字,显示数字;如果是空格,递归出连续空格并显示空白,一直到第一位数字为止。


-----代码片段4开始

//左键 
function divClickLeft(divId) {
    if ($.inArray(divId, arrDoBomb) < 0) {  //不是用户标记的雷时,用户标记过得雷左键时无效果
        if ($.inArray(divId, arrBomb) >= 0) {
            isFinish = true;
            $("#" + divId).html("<img src=\"bomb.png\" style=\"width:" + WidthHeight + "px;height:" + WidthHeight + "px\" >");
            alert("地雷啊,你被炸了。再接再厉。");   //$("#btnBegin").click(); //开始按钮
            //$("#custMessage").unbind('DOMNodeInserted');
            $("#custMessage").html("排雷中...");
            setTimeout(function () { bombBangedAndEnd(1, false); }, 500);
        }
        else if ($.inArray(divId, arrBlank) >= 0) {    //点击空格的时候,其他连续的空格也展示出来奥。
            if ($.inArray(divId, arrDoBomb) >= 0) {   //标记为雷
                $("#" + divId).addClass("divOpen");
                $("#" + divId).html("");
            }
            getContinuousBlankDiv(divId);
        }
        else if ($.inArray(divId, arrNumber) >= 0) {   //数字,直接显示
            $.each(arrNumberContent, function (k, v) {
                if (v.Key == divId) {
                    $("#" + divId).html(v.Val);
                    $("#" + divId).addClass("divOpen");
                    if (getIsOdd(v.Val) == true) { //奇偶数显示不同颜色
                        $("#" + divId).addClass("divOdd");
                    } else {
                        $("#" + divId).addClass("divEven");
                    }
                    return false;
                }
            });
        }
        var _indexDoBomb = $.inArray(divId, arrDoBomb);
        if (_indexDoBomb >= 0) arrDoBomb.splice(_indexDoBomb, 1);
        if ($.inArray(divId, arrDomanage) < 0) arrDomanage.push(divId);
        isFinished();
    }
}

-----代码片段4结束


【5】 中键滚轮事件:快速开启雷区。当明确周边雷时,快速开启周边非雷的内容(包含空格递归)。如果标记的雷错误,就爆炸,gameOver。


-----代码片段5开始

//中键 
function divClickMiddle(divId) {
    if ($.inArray(divId, arrDomanage) < 0 || $.inArray(divId, arrDoBomb) >= 0) { //未知区域 || 被标记为雷 (当前点击的这是未知区域)
        //周圈去背景色
        var _aroundAll = new Array();
        $.each(getAroundDivByMiddle(divId), function (k, _id) { //计算周边的布局
            if ($.inArray(_id, _aroundAll) < 0) _aroundAll.push(_id);
            $("#" + _id).addClass("divCanelAround"); //周边闪烁(模拟)
        });
        setTimeout(function () {
            $.each(_aroundAll, function (k, v) {
                $("#" + v).removeClass("divCanelAround");
            });
        }, 200);  //0.2 秒后周边停止闪烁
    }
    else { //已知区域(当前点击的这是已知区域)
        if ($.inArray(divId, arrNumber) > -1) //如果是已知区域的数字 ,空格时不操作
        {
            getAroundByClickMiddleButton(divId);
        }
    }
    isFinished();
}
//计算周边的布局
function getAroundDivByMiddle(id) {
    var rB = 1, rE = 1, cB = 1, cE = 1;
    var rCurr = 1, cCurr = 1;
    rCurr = parseInt(id.split('_')[0]); //"1_1"
    cCurr = parseInt(id.split('_')[1]); //"3_5"
    rB = rCurr - 1; if (rB < 1) rB = 1;
    rE = rCurr + 1; if (rE > rows) rE = rows;
    cB = cCurr - 1; if (cB < 1) cB = 1;
    cE = cCurr + 1; if (cE > cols) cE = cols;
    var _arrReturn = new Array();
    for (var i = rB; i <= rE; i++) {
        for (var j = cB; j <= cE; j++) {
            var _id = i.toString() + "_" + j.toString();
            if ($.inArray(_id, _arrReturn) < 0) {
                _arrReturn.push(_id);
            }
        }
    }
    return _arrReturn;
}
//当中键点击的是已知区域数字时,周圈全部显示 数值一层,空格递归
function getAroundByClickMiddleButton(id) {
    var _bomb = new Array();
    var _blank = new Array();
    var _num = new Array();
    var _aroundAllDoNot = new Array(); //_aroundAll
    var _arrDoBomb = new Array();
    $.each(getAroundDivByMiddle(id), function (k, _id) {
        if (_id != id) {
            if (arrDoBomb.length > 0 && $.inArray(_id, arrDoBomb) >= 0) {
                if ($.inArray(_id, _arrDoBomb) < 0) _arrDoBomb.push(_id); //缓存起来:这一圈中,用户打过雷标记的
            }
            if ($.inArray(_id, arrDomanage) < 0) { //没有遍历过的,才继续操作 && 没有被用户标记为雷
                // if ($.inArray(_id, arrTemp) < 0 && $.inArray(_id, arrDoBomb) < 0) { //没有遍历过的,才继续操作 && 没有被用户标记为雷
                if ($.inArray(_id, _aroundAllDoNot) < 0 && _id != id) _aroundAllDoNot.push(_id); //周圈闪烁的缓存起来 //_aroundAll
                if ($.inArray(_id, arrBomb) >= 0) { //是雷
                    if ($.inArray(_id, _bomb) < 0) _bomb.push(_id); //缓存起来
                }
                if ($.inArray(_id, arrBlank) >= 0) {
                    if ($.inArray(_id, _blank) < 0) _blank.push(_id); //缓存起来
                }
                if ($.inArray(_id, arrNumber) >= 0) {
                    if ($.inArray(_id, _num) < 0) _num.push(_id); //缓存起来
                }
            }
        }
    });
    var _lengths = _bomb.length;
    if (_lengths == 0) { //没有雷
        for (var i = 0; i < _blank.length; i++) {
            if ($.inArray(_blank[i], arrDomanage) < 0) arrDomanage.push(_blank[i]);
            if ($.inArray(_blank[i], arrTemp) < 0) arrTemp.push(_blank[i]);
            $("#" + _blank[i]).addClass("divOpen");
            $("#" + _blank[i]).html("");
            getContinuousBlankDiv(_blank[i]);
        }
        for (var i = 0; i < _num.length; i++) {
            //如果是数字,则显示,不再往下递归。这样可以保证空白下的第一层数字显示。
            var text = getNumber(_num[i]);
            $("#" + _num[i]).html(text);
            $("#" + _num[i]).addClass("divOpen");
            if ($.inArray(_num[i], arrDomanage) < 0) arrDomanage.push(_num[i]);
            if ($.inArray(_num[i], arrTemp) < 0) arrTemp.push(_num[i]);
            if (getIsOdd(text) == true) {
                $("#" + _num[i]).addClass("divOdd");
            } else {
                $("#" + _num[i]).addClass("divEven");
            }
        }
    }
    else if (_lengths >= 1) {
        var _wrongDoBomb = [];
        _arrDoBomb.forEach(function (v) {
            if ($.inArray(v, arrBomb) < 0) { //如果雷标记打错了,就爆炸。
                _wrongDoBomb.push(v);
            }
        });
        if (_wrongDoBomb.length == 0) {
            $("#" + id).addClass("divCanel"); //显示红叉号
            setTimeout(function () {
                $("#" + id).removeClass("divCanel");
            }, 200); //0.2秒后 去掉红叉号
            $.each(_aroundAllDoNot, function (k, v) {  //_aroundAll
                $("#" + v).addClass("divCanelAround"); //周边闪烁
            });
            setTimeout(function () {
                $.each(_aroundAllDoNot, function (k, v) { //_aroundAll
                    $("#" + v).removeClass("divCanelAround");
                });
            }, 200);  //0.2 秒后周边停止闪烁
        }
        else {
            isFinish = true;
            $.each(_wrongDoBomb, function (k, v) {
                $("#" + v).html("<img src=\"cancel.png\" style=\"width:" + WidthHeight + "px;height:" + WidthHeight + "px\" >");
            });
            alert("地雷啊,你被炸了。再接再厉。");   //$("#btnBegin").click(); //开始按钮
            //$("#custMessage").unbind('DOMNodeInserted');
            $("#custMessage").html("排雷中...");
            setTimeout(function () { bombBangedAndEnd(1, false); }, 500);
        }
    }
}

-----代码片段5结束


【6】右键事件:点击一下,标记为雷,再一下,取消雷标记,标记为问号。仅当标记为雷时,左键和中键事件失效。


-----代码片段6开始

//右键 表示设定为 “雷|疑问|取消标记”
function divClickRight(divId) {
    if (($.inArray(divId, arrDomanage) < 0 && $("#" + divId).html() == "") || isNaN($("#" + divId).html()) == true) {
        if ($.inArray(divId, arrDomanage) < 0) {
            if ($("#" + divId).html().indexOf("mark2.png") > -1) { //标记为问号时,再点击右键,跳到这里。
                $("#" + divId).html("");
            }
            else { //第一次点击右键时,标记为雷
                $("#" + divId).html("<img src=\"mark1.png\" style=\"width:" + WidthHeight + "px;height:" + WidthHeight + "px\" >");
                if ($.inArray(divId, arrDoBomb) < 0) {
                    arrDoBomb.push(divId);
                    numResidue = numResidue - 1;
                }
                if ($.inArray(divId, arrDomanage) < 0) arrDomanage.push(divId);
            }
        }
        else { //已经标记为雷时,再点击右键,跳到这里。
            $("#" + divId).html("<img src=\"mark2.png\" style=\"width:" + WidthHeight + "px;height:" + WidthHeight + "px\" >");
            numResidue = numResidue + 1;
            var _indexDoBomb = $.inArray(divId, arrDoBomb);
            if (_indexDoBomb >= 0) {
                arrDoBomb.splice(_indexDoBomb, 1);
            }
            var _indexDomanage = $.inArray(divId, arrDomanage);
            if (_indexDomanage >= 0) {
                arrDomanage.splice(_indexDomanage, 1);
            }
        }
        $("#spanResidue").html(numResidue); //显示剩余多少雷数
        isFinished();
    }
}


-----代码片段6结束


【7】 键盘事件:数字键“1”相当为鼠标左键,数字键“2”相当为鼠标中键,数字键“3”相当为鼠标右键,数字键“4”为提示键;以上数字键大小键盘均可。方向键上下左右调整雷区内焦点移动。


-----代码片段7开始

//根据计算好的雷区,生成div ,并绑定鼠标和键盘事件
function appendDiv() {
...
/*键盘*/
    $(document).unbind("keydown");
    $(document).bind("keydown", function (e) {
        if (iskeyCount == 0) { //功能限制。 防止长按键盘的操作。不使用 keyUp 是因为按键弹起后再执行,感觉太慢有延迟感觉。 keypress 与 keydown 区别不大。
            if ($("#fieldset").is(":hidden") == false && isFinish == false) {
                keyDown(e.keyCode);
            }
            iskeyCount++;
        }
    });
    $(document).unbind("keyup");
    $(document).bind("keyup", function (e) {
        iskeyCount = 0;
    });
...
}
//键盘操作 (上下左右 键盘数字1、2、3、4)
function keyDown(keyCode) {
    if (focusDivId != "") {
        var _focusDivId = focusDivId;
        if (keyCode == 37) { //左
            var _colId = parseInt(_focusDivId.split('_')[1]) - 1;
            for (var b = _colId; b >= 1; b--) {
                _focusDivId = _focusDivId.split('_')[0] + "_" + b.toString();
                if ($.inArray(_focusDivId, arrDomanage) <= -1 || $.inArray(_focusDivId, arrNumber) > -1) { //未标记的或数字都可以使用键盘获得焦点
                    $("#" + focusDivId).removeClass("divColMouse"); //去掉老焦点
                    $("#" + _focusDivId).addClass("divColMouse");
                    $("#" + _focusDivId).focus(); //设置新焦点
                    focusDivId = _focusDivId;
                    return false;
                }
            }
        }
        else if (keyCode == 38) { //上
            var _rowId = parseInt(_focusDivId.split('_')[0]) - 1;
            for (var b = _rowId; b >= 1; b--) {
                _focusDivId = b.toString() + "_" + _focusDivId.split('_')[1];
                if ($.inArray(_focusDivId, arrDomanage) <= -1 || $.inArray(_focusDivId, arrNumber) > -1) {
                    $("#" + focusDivId).removeClass("divColMouse");
                    $("#" + _focusDivId).addClass("divColMouse");
                    $("#" + _focusDivId).focus();
                    focusDivId = _focusDivId;
                    return false;
                }
            }
        }
        else if (keyCode == 39) { //右
            var _colId = parseInt(_focusDivId.split('_')[1]) + 1;
            for (var b = _colId; b <= cols; b++) {
                _focusDivId = _focusDivId.split('_')[0] + "_" + b.toString();
                if ($.inArray(_focusDivId, arrDomanage) <= -1 || $.inArray(_focusDivId, arrNumber) > -1) {
                    $("#" + focusDivId).removeClass("divColMouse");
                    $("#" + _focusDivId).addClass("divColMouse");
                    $("#" + _focusDivId).focus();
                    focusDivId = _focusDivId;
                    return false;
                }
            }
        }
        else if (keyCode == 40) { //下
            var _rowId = parseInt(_focusDivId.split('_')[0]) + 1;
            for (var b = _rowId; b <= rows ; b++) {
                _focusDivId = b.toString() + "_" + _focusDivId.split('_')[1];
                if ($.inArray(_focusDivId, arrDomanage) <= -1 || $.inArray(_focusDivId, arrNumber) > -1) {
                    $("#" + focusDivId).removeClass("divColMouse");
                    $("#" + _focusDivId).addClass("divColMouse");
                    $("#" + _focusDivId).focus();
                    focusDivId = _focusDivId;
                    return false;
                }
            }
        }
        else if (keyCode == 49 || keyCode == 97) {//左键
            divClickLeft(focusDivId);
        }
        else if (keyCode == 50 || keyCode == 98) { //中键
            divClickMiddle(focusDivId);
        }
        else if (keyCode == 51 || keyCode == 99) { //右键
            divClickRight(focusDivId);
        }
        else if (keyCode == 52 || keyCode == 100) { //扫雷结果提示。 主键盘键4 或 小键盘4
            helpClearBomb();
        }
    }
}

-----代码片段7结束


【8】 扫雷是否完成,并显示简单的动画效果


-----代码片段8开始

//判断扫雷是否结束
function isFinished() {
    if (arrBomb.sort().toString() == arrDoBomb.sort().toString()
        && arrAllDivId.sort().toString() == arrDomanage.sort().toString()) {
        isFinish = true;
        $("#custMessage").html("<b>恭喜,扫雷完毕,用时" + $("#spanSecond").html() + "秒。</b>");
        //$("#custMessage").unbind("DOMNodeInserted");
        //bombBangedAndEnd(1, true);
        setTimeout(function () { bombBangedAndEnd(1, true); }, 500);
    }
}
//引爆和完成后
function bombBangedAndEnd(bRow, issuccess) {
    $("#progress").show();
    for (var j = 1; j <= cols; j++) {
        var _id = bRow.toString() + "_" + j.toString();
        if ($("#" + _id + " :eq(0)").attr("src") == "cancel.png") {
            $("#" + _id + " :eq(0)").remove();
        }
        if ($.inArray(_id, arrBomb) >= 0) {
            $("#" + _id).html("<img src=\"bomb.png\" style=\"width:" + WidthHeight + "px;height:" + WidthHeight + "px\" >");
        }
    }
    if (bRow <= rows) {
        $("#progress").height(bRow * (WidthHeight + 1));
        setTimeout(function () { bombBangedAndEnd(bRow + 1, issuccess); }, 200);
    }
    else {
        $("#progress").hide();
        if (!issuccess) { //不是排雷完毕,就清空备注
            $("#custMessage").html("");
        }
    }
}


-----代码片段8结束


贴完上面的代码,jquery web网页版的扫雷游戏就到了一个段落~~博主正在学习jquery mobile,希望能够移植到手机端。

毕竟手机游戏才是现在的主流。敬请期待!!!


转发注明:www.suchso.com 

点击阅读本文所属分类的更多文章: 项目实战 。和高手一起交流:346717337
友荐云推荐

未注明转发、原文均为本站原创。分享本文请注明 原文链接

给您更多信息和帮助

在这里您可以找到更多:

技术交流群:346717337 Jquery插件交流

投稿:suchso@vip.qq.com

承接:企业网站门户/微网站/微商城/CMS系统/微信公众号运营/业务咨询

抢天猫双11红包
推荐使用阿里云服务器
echarts教程系列
本月最热文章

微信扫一扫,徜徉悠嘻网,您的休闲乐园

微信公众号:快乐每一天

随机文章
标签

技术交流群:346717337

投稿:suchso@vip.qq.com

专业专注:企业网站门户/微网站/微商城/CMS系统/微信公众号运营/付费问题咨询