【JS小游戏】游戏编程初体验之扫雷

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/WuZuoDingFeng/article/details/55517652

前言

昨天接触到一个叫做net的游戏,类似接点灯的那种类型,在一个方阵中随机分配了一些点,然后给了一些管道让玩家将其连通才算过关,完了几把就上瘾了。但是这个游戏是PC端的单机游戏,不方便我在其他地方随时可以玩,于是想自己写一个类似的游戏出来,但是发现自己水平有限,一时没有想出该组合实现管道分布的算法,就只能留着后面慢慢想了,我就退而求其次的写了一个扫雷游戏,也算是进入了游戏这个行业了吧(自我安慰而已啦)。扫雷的游戏相对net来少了那个管道的分布算法,是随机的将雷分不到方阵中,然后由用户一步一步的确定雷的位置。算法相对来说较为简单,具体算法我就不想多做赘述了,在文中末尾记录该小游戏的完整js代码,请各位看官雅正。

界面截图

这里写图片描述

测试demo页面

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title></title>
</head>
<body>
<div>
    <label><span>x:</span><input id="x"/></label>
    <label><span>y:</span><input id="y"/></label>
    <label><span>mine:</span><input id="mine"/></label>
    <input type="submit" id="submit"/>
    <div id="game_container">
    </div>
</div>
</body>
<script type="text/javascript" src="js/jquery-1.11.0.js"></script>
<script type="text/javascript" src="js/sweeper.js"></script>
<script>
    $("#submit").click(function () {
        sweeper.init({
            x: $("#x").val(),
            y: $("#y").val(),
            mine: $("#mine").val(),
            container: $("#game_container"),
            start: function (data) {
            },
            pass: function (data) {
            },
            over: function (data) {
            }
        })
    })
</script>
</html>

核心的js代码 sweeper.js

(function (w, $) {
    var sweeper = {
        data: {
            globalData: {
                isStarted: false,
                real: 0,
                rest: 0
            }
        },
        /**
         * 初始化游戏
         * @param {Object} params初始化参数对象
         */
        init: function (params) {
            //初始化参数
            var globalData = sweeper.data.globalData
            globalData.x = params && params.x ? params.x : 10
            globalData.y = params && params.y ? params.y : 10
            globalData.mine = params && params.mine ? params.mine : 30
            globalData.container = params && params.container ? params.container : $("#game_container")
            globalData.start = params && params.start ? params.start : function (data) {
                }
            globalData.pass = params && params.pass ? params.pass : function (data) {
                    alert("you are winner")
                }
            globalData.over = params && params.over ? params.over : function (data) {
                    alert("game over")
                }
            globalData.matrix = new Array()

            //初始化游戏容器
            globalData.container.html("")
            globalData.container.css("line-height", "0px")
            $("head").append("<style>.grid {width: 1.2em;height: 1.2em;font-size: 1em;margin: 0px;padding: 0px;}</style>")

            //计算雷区面积和地雷出现概率
            var maxGrid = globalData.x * globalData.y
            var mineP = globalData.mine / maxGrid

            //构建雷区
            for (var i = 0; i < globalData.y; i++) {
                for (var j = 0; j < globalData.x; j++) {
                    //当前位置随机生成地雷
                    var isMine = Math.random() <= mineP ? true : false
                    //如果生成了地雷,将游戏全局变量的真实地雷数加1
                    if (isMine) {
                        globalData.real++
                    }

                    //构造位置对象,并保存当前位置是否有雷和排雷状态
                    var grid = {
                        x: j,
                        y: i,
                        isMine: isMine,
                        isSweeped: false
                    }
                    globalData.matrix.push(grid);

                    //向页面游戏容器加入位置格子,并未格子绑定排雷事件
                    globalData.container.append("<button class='grid' onclick='sweeper.sweep(" + j + "," + i + ")'>&nbsp</button>")
                }
                globalData.container.append("<br />")
            }

            //保存页面格子,并初始化当前雷区格子剩余量
            globalData.butMatrix = globalData.container.children("button")
            globalData.rest = globalData.butMatrix.length

        },
        /**
         * 排雷操作
         * @param {Object} x 当前位置横向索引
         * @param {Object} y 当前位置纵向索引
         */
        sweep: function (x, y) {
            var globalData = sweeper.data.globalData

            /**
             * 获取指定位置的详细信息
             * @param {Object} x 位置横向索引
             * @param {Object} y 位置纵向索引
             */
            function getGrid(x, y) {
                if (x < 0 || x >= globalData.x) {
                    return
                } else if (y < 0 || y >= globalData.y) {
                    return
                } else {
                    return globalData.matrix[globalData.y * y + x]
                }
            }

            /**
             * 获取指定位置的格子对象
             * @param {Object} x 位置横向索引
             * @param {Object} y 位置纵向索引
             */
            function getGridBut(x, y) {
                if (x < 0 || x >= globalData.x) {
                    return
                } else if (y < 0 || y >= globalData.y) {
                    return
                } else {
                    return $(globalData.butMatrix[globalData.y * y + x])
                }
            }

            /**
             * 获取指定位置周边位置详情列表
             * @param {Object} x 中心位置横向索引
             * @param {Object} y 中心位置纵向索引
             */
            function listSrd(x, y) {
                var srdGrid = new Array();

                function pushGrid(obj) {
                    if (obj) {
                        srdGrid.push(obj)
                    }
                }

                pushGrid(getGrid(x - 1, y - 1))
                pushGrid(getGrid(x - 1, y))
                pushGrid(getGrid(x - 1, y + 1))
                pushGrid(getGrid(x + 1, y - 1))
                pushGrid(getGrid(x + 1, y))
                pushGrid(getGrid(x + 1, y + 1))
                pushGrid(getGrid(x, y + 1))
                pushGrid(getGrid(x, y - 1))
                return srdGrid
            }

            /**
             * 踩雷,游戏结束
             */
            function dead() {
                globalData.over('') //踩雷调用
                for (var i = 0; i < globalData.matrix.length; i++) {
                    var grid = globalData.matrix[i]
                    if (!grid.isSweeped) {
                        var but = getGridBut(grid.x, grid.y)

                        if (grid.isMine) {
                            but.css("background-color", "black")
                        }

                        but.attr("disabled", "disabled")
                    }
                }
            }

            /**
             * 地雷完全排除,顺利通关
             */
            function pass() {
                globalData.pass('') //通关调用
                for (var i = 0; i < globalData.matrix.length; i++) {
                    var grid = globalData.matrix[i]
                    if (!grid.isSweeped) {
                        var but = getGridBut(grid.x, grid.y)

                        if (grid.isMine) {
                            but.css("background-color", "red")
                        }
                        but.attr("disabled", "disabled")
                    }
                }
            }

            /**
             * 在未踩雷的情况下进行排雷操作
             * @param {Object} grid 排雷位置
             */
            function compute(grid) {
                if (!grid.isSweeped) {
                    grid.isSweeped = true
                    globalData.rest--
                    if (globalData.rest == globalData.real) {
                        pass()
                    }
                    var srdGrid = listSrd(grid.x, grid.y)
                    var gridBut = globalData.butMatrix[globalData.y * grid.y + grid.x]
                    $(gridBut).css("background-color", "white")
                    $(gridBut).attr("disabled", "disabled")
                    var count = 0;
                    for (var i = 0; i < srdGrid.length; i++) {
                        if (srdGrid[i].isMine) {
                            count++
                        }
                    }
                    if (count == 0) {
                        for (var i = 0; i < srdGrid.length; i++) {
                            compute(srdGrid[i])
                        }
                    } else {
                        $(gridBut).html(count)
                    }
                }
            }

            // 首次点击时算开始
            if (!globalData.isStarted) {
                globalData.start('') //开始调用
                globalData.isStarted = true
            }

            //排雷
            var grid = getGrid(x, y)
            if (grid) {
                if (grid.isMine) {
                    dead()
                } else {
                    compute(grid)
                }
            }
        }
    }

    w.sweeper = sweeper

})(window, $)
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页