zoukankan      html  css  js  c++  java
  • 累了休息一会儿吧——分享一个JavaScript版扫雷游戏

      周末闲来无事写了一个JavaScript版扫雷游戏,现在把源代码分享出来,共同学习。

      扫雷游戏的原理大家可以参考这篇文章:http://www.cnblogs.com/goodwin/archive/2010/03/22/1691871.html

      JavaScript代码:

    (function () {
        var FLM = function (id,rowCount,colCount, minLandMineCount, maxLandMineCount) {
            if (!(this instanceof FLM))
                return new FLM(id, rowCount, colCount, minLandMineCount, maxLandMineCount);
            this.doc = document;
            this.table = this.doc.getElementById(id);
            this.cells = this.table.getElementsByTagName("td");//小格子
            this.rowCount = rowCount || 10;//格子行数
            this.colCount = colCount || 10;//格子列数
            this.landMineCount = 0;//地雷个数
            this.markLandMineCount = 0;//标记的地雷个数
            this.minLandMineCount = minLandMineCount || 10;//地雷最少个数
            this.maxLandMineCount = maxLandMineCount || 20;//地雷最多个数
            this.arrs = [];//格子对应的数组
            this.beginTime = null;//游戏开始时间
            this.endTime = null;//游戏结束时间
            this.currentSetpCount = 0;//当前走的步数
            this.endCallBack = null;//游戏结束时的回调函数
            this.landMineCallBack = null;//标记为地雷时更新剩余地雷个数的回调函数
            this.doc.oncontextmenu = function () {//禁用右键菜单
                return false;
            };
            this.drawMap();
        };
    
        FLM.prototype = {
            //获取元素
            $: function (id) {
                return this.doc.getElementById(id);
            },
            //画地图
            drawMap: function () {
                var tds = [];
                for (var i = 0; i < this.rowCount; i++) {
                    tds.push("<tr>");
                    for (var j = 0; j < this.colCount; j++) {
                        tds.push("<td id='m" + i + "" + j + "'></td>");
                    }
                    tds.push("</td>");
                }
                this.table.innerHTML = tds.join("");
            },
            //初始化,一是设置数组默认值为0,二是确定地雷个数
            init: function () {
                for (var i = 0; i < this.rowCount; i++) {
                    this.arrs[i] = [];
                    for (var j = 0; j < this.colCount; j++) {
                        this.arrs[i][j] = 0;
                    }
                }
                this.landMineCount = this.selectFrom(this.minLandMineCount, this.maxLandMineCount);
            },
            //把是地雷的数组项的值设置为9
            landMine: function () {
                var allCount = this.rowCount * this.colCount - 1,
                    tempArr = {};
                for (var i = 0; i < this.landMineCount; i++) {
                    var randomNum = this.selectFrom(0, allCount),
                        rowCol = this.getRowCol(randomNum);
                    if (randomNum in tempArr) {
                        i--;
                        continue;
                    }
                    this.arrs[rowCol.row][rowCol.col] = 9;
                    tempArr[randomNum] = randomNum;
                }
            },
            //计算其他格子中的数字
            calculateNoLandMineCount: function () {
                for (var i = 0; i < this.rowCount; i++) {
                    for (var j = 0; j < this.colCount; j++) {
                        if (this.arrs[i][j] == 9)
                            continue;
                        if (i > 0 && j > 0) {
                            if (this.arrs[i - 1][j - 1] == 9)
                                this.arrs[i][j]++;
                        }
                        if (i > 0) {
                            if (this.arrs[i - 1][j] == 9)
                                this.arrs[i][j]++;
                        }
                        if (i > 0 && j < this.colCount - 1) {
                            if (this.arrs[i - 1][j + 1] == 9)
                                this.arrs[i][j]++;
                        }
                        if (j > 0) {
                            if (this.arrs[i][j - 1] == 9)
                                this.arrs[i][j]++;
                        }
                        if (j < this.colCount - 1) {
                            if (this.arrs[i][j + 1] == 9)
                                this.arrs[i][j]++;
                        }
                        if (i < this.rowCount - 1 && j > 0) {
                            if (this.arrs[i + 1][j - 1] == 9)
                                this.arrs[i][j]++;
                        }
                        if (i < this.rowCount - 1) {
                            if (this.arrs[i + 1][j] == 9)
                                this.arrs[i][j]++;
                        }
                        if (i < this.rowCount - 1 && j < this.colCount - 1) {
                            if (this.arrs[i + 1][j + 1] == 9)
                                this.arrs[i][j]++;
                        }
                    }
                }
            },
            //给每个格子绑定点击事件(左键和右键)
            bindCells: function () {
                var self = this;
                for (var i = 0; i < this.rowCount; i++) {
                    for (var j = 0; j < this.colCount; j++) {
                        (function (row, col) {
                            self.$("m" + i + "" + j).onmousedown = function (e) {
                                e = e || window.event;
                                var mouseNum = e.button;
                                var className = this.className;
                                if (mouseNum == 2) {
                                    if (className == "flag") {
                                        this.className = "";
                                        self.markLandMineCount--;
                                    } else {
                                        this.className = "flag";
                                        self.markLandMineCount++;
                                    }
                                    if (self.landMineCallBack) {
                                        self.landMineCallBack(self.landMineCount - self.markLandMineCount);
                                    }
                                } else if (className != "flag") {
                                    self.openBlock.call(self, this, row, col);
                                }
                            };
                        })(i,j);
                    }
                }
            },
            //展开无雷区域
            showNoLandMine: function (x, y) {
                for (var i = x - 1; i < x + 2; i++)
                    for (var j = y - 1; j < y + 2; j++) {
                        if (!(i == x && j == y)) {
                            var ele = this.$("m" + i + "" + j);
                            if (ele && ele.className == "") {
                                this.openBlock.call(this, ele, i, j);
                            }
                        }
                    }
            },
            //显示
            openBlock: function (obj, x, y) {
                if (this.arrs[x][y] != 9) {
                    this.currentSetpCount++;
                    if (this.arrs[x][y] != 0) {
                        obj.innerHTML = this.arrs[x][y];
                    }
                    obj.style.backgroundColor = "green";
                    obj.className = "normal";
                    if (this.currentSetpCount + this.landMineCount == this.rowCount * this.colCount) {
                        this.success();
                    }
                    if (this.arrs[x][y] == 0) {
                        this.showNoLandMine.call(this, x, y);
                    }
                } else {
                    this.failed();
                }
            },
            //显示地雷
            showLandMine: function () {
                for (var i = 0; i < this.rowCount; i++) {
                    for (var j = 0; j < this.colCount; j++) {
                        if (this.arrs[i][j] == 9) {
                            this.$("m" + i.toString() + j).className = "landMine";
                        }
                    }
                }
            },
            //显示所有格子信息
            showAll: function () {
                for (var i = 0; i < this.rowCount; i++) {
                    for (var j = 0; j < this.colCount; j++) {
                        if (this.arrs[i][j] == 9) {
                            this.$("m" + i.toString() + j).className = "landMine";
                        } else {
                            if (this.arrs[i][j] != 0)
                                this.$("m" + i.toString() + j).innerHTML = this.arrs[i][j];
                        }
                    }
                }
            },
            //清除显示的格子信息
            hideAll: function () {
                for (var i = 0; i < this.rowCount; i++) {
                    for (var j = 0; j < this.colCount; j++) {
                        var tdCell = this.$("m" + i.toString() + j);
                        tdCell.className = "";
                        tdCell.innerHTML = "";
                    }
                }
            },
            //删除格子绑定的事件
            disableAll: function () {
                for (var i = 0; i < this.rowCount; i++) {
                    for (var j = 0; j < this.colCount; j++) {
                        var tdCell = this.$("m" + i.toString() + j);
                        tdCell.onmousedown = null;
                    }
                }
            },
            //游戏开始
            begin: function () {
                this.currentSetpCount = 0;//开始的步数清零
                this.markLandMineCount = 0;
                this.beginTime = new Date();//游戏开始时间
                this.hideAll();
                this.bindCells();
            },
            //游戏结束
            end: function () {
                this.endTime = new Date();//游戏结束时间
                if (this.endCallBack) {//如果有回调函数则调用
                    this.endCallBack();
                }
            },
            //游戏成功
            success: function () {
                this.end();
                this.showAll();
                this.disableAll();
                alert("Congratulation!");
            },
            //游戏失败
            failed: function () {
                this.end();
                this.showAll();
                this.disableAll();
                alert("GAME OVER!");
            },
            //通数值找到行数和列数
            getRowCol: function (val) {
                return {
                    row: parseInt(val / this.colCount),
                    col: val % this.colCount
                };
            },
            //获取一个随机数
            selectFrom: function (iFirstValue, iLastValue) {
                var iChoices = iLastValue - iFirstValue + 1;
                return Math.floor(Math.random() * iChoices + iFirstValue);
            },
            eventFire: function (el, etype) {
                if (el.fireEvent) {
                    (el.fireEvent('on' + etype));
                } else {
                    var evObj = document.createEvent('Events');
                    evObj.initEvent(etype, false, false);
                    el.dispatchEvent(evObj);
                }
            },
            //入口函数
            play: function () {
                this.init();
                this.landMine();
                this.calculateNoLandMineCount();
            }
        };
    
        window.FLM = FLM;
    })();

      HTML部分:

    <div id="FLM_main">
        <table id="landmine">
        </table>
        <div id="operation">
            <div class="tip">剩余雷数:<span class="light red" id="landMineCount">0</span></div>
            <div class="tip">持续时间: <span class="light f60" id="costTime">0</span> s</div>
            <input type="button" id="showLandMine" value="显示地雷" /><br />
            <input type="button" id="showAll" value="显示全部" /><br />
            <input type="button" id="begin" value="开始游戏" /><br />
            <div class="tip txtleft">提示:
                <ul>
                    <li>1、点击“开始游戏”游戏开始计时</li>
                    <li>2、游戏过程中点击“显示地雷”或“显示全部”游戏将会结束</li>
                </ul>
            </div>
        </div>
    </div>

      调用部分:

    window.onload = function () {
        var flm = FLM("landmine", 10, 10),
            doc = document,
            landMineCountElement = doc.getElementById("landMineCount"),
            timeShow = doc.getElementById("costTime"),
            showLandMineButton = doc.getElementById("showLandMine"),
            showAllButton = doc.getElementById("showAll"),
            beginButton = doc.getElementById("begin"),
            timeHandle = null;
        flm.endCallBack = function () {
            clearInterval(timeHandle);
        };
        flm.landMineCallBack = function (count) {
            landMineCountElement.innerHTML = count;
        };
    
        //为“开始游戏”按钮绑定事件
        beginButton.onclick = function () {
            flm.play();//初始化
    
            //显示地雷个数
            landMineCountElement.innerHTML = flm.landMineCount;
    
            //为“显示地址”按钮绑定事件
            showLandMineButton.onclick = function () {
                if (confirm("显示地雷游戏将结束?")) {
                    flm.failed();
                    flm.showLandMine();
                }
            };
    
            //为“显示全部”按钮绑定事件
            showAllButton.onclick = function () {
                if (confirm("显示全部游戏将结束?")) {
                    flm.failed();
                    flm.showAll();
                }
            };
    
            //开始
            flm.begin();
    
            //更新花费时间
            timeHandle = setInterval(function () {
                timeShow.innerHTML = parseInt((new Date() - flm.beginTime) / 1000);
            }, 1000);
        };
    }

      布局用的是table,所以FLM三个参数的第一个就是table的ID,第二个参数为最少地雷个数,第三个参数为最多地雷个数。

      运行效果:

    Demo
    剩余雷数:0
    持续时间: 0 s



    提示:
    • 1、点击“开始游戏”游戏开始计时
    • 2、游戏过程中点击“显示地雷”或“显示全部”游戏将会结束

      各位朋友们,果断地把你们的成绩截图晒出来吧!!!

  • 相关阅读:
    JAVA假期第五天2020年7月10日
    JAVA假期第四天2020年7月9日
    JAVA假期第三天2020年7月8日
    JAVA假期第二天2020年7月7日
    JAVA假期第一天2020年7月6日
    CTF-sql-group by报错注入
    CTF-sql-order by盲注
    CTF-sql-sql约束注入
    CTF-sql-万能密码
    X-Forwarded-for漏洞解析
  • 原文地址:https://www.cnblogs.com/jscode/p/2677064.html
Copyright © 2011-2022 走看看