JS前端迷宫生成

2 篇文章 0 订阅
本文介绍了一个使用HTML5 Canvas和JavaScript实现的迷宫生成算法。通过Vue.js进行交互,优化了之前的C++版本,提高了算法效率,减少了循环嵌套。代码中详细解释了迷宫生成的步骤,包括初始化地图、检查边界和访问状态、获取可行路径等。同时,文章强调迷宫尺寸和起点设置的重要性,以避免错误和环路问题。最后,展示了生成并绘制迷宫的完整过程。
摘要由CSDN通过智能技术生成

首先,这段代码是可以直接使用的,只需要浏览器即可。可以参见下图:

 

但是有一点要说明,由于本人在自学vue,所以调用vue.js文件。但是,这无伤大雅,可以改写函数绑定的方法,便可忽略vue带来的影响。

当然,也可以下载vue.js文件,修改引用的路径,便可以使用完整的功能。

由于之前使用C++写过同样的算法(深度优先或递归回溯),对栈的使用有一定青睐,JS数组同样具有栈的功能,所以做了一点改写。当然,这个算法比C++版优化了很多,具体还是提升了速度。主要还是之前用了三个循环嵌套,现在感觉并无必要。还有之前使用各种插件来绘图,感觉比较麻烦,或许html的canvas才是正解,当然,这同样失去了c++的调试环境,这时候只能靠自己对错误的敏感度了。

接下来说一些注意事项:

width:迷宫的宽度,必须为奇数

height: 迷宫的高度,必须为奇数

beginX:起点X,推荐为奇数

beginY: 起点Y,推荐为奇数

size:每个方格的宽度

如果没有按照上边的要求设置,可能会出现错误,比如起点偶数位置,就会产生环路等问题。

<html>

<head>
    <title>canvas studio</title>
    <script type="text/javascript" src="../js/vue.js"></script>
    <style>
        body{
            background-color: rgb(195, 206, 205);
        }
    </style>
</head>

<body>
    <div id="app2">
        <canvas width="625" height="465" id="canvas"
            style="position: absolute;right:10;top:10;border: 1px solid #000000;">
        </canvas>
        <button v-on:click="draw(width,height,beginX,beginY,size)">{{ btdraw }}</button>
    </div>
</body>
<script>

    var app2 = new Vue({
        el: '#app2',
        data: {
            btdraw: '生产迷宫',
            width: 125,
            height: 93,
            beginX: 1,
            beginY: 1,
            size: 5,
            draw: function (width, height, beginX, beginY, size) {
                var map = initMap(width, height);
                var newmap = changeMap(map, beginX, beginY);
                drawMap(newmap, size);
            }
        }
    })
    //初始化地图
    function initMap(width, height) {
        var map = new Array(width);
        for (i = 0; i < map.length; i++) {
            var temp = new Array(height);
            for (j = 0; j < temp.length; j++) {
                if (i % 2 == 0 || j % 2 == 0) temp[j] = 0;
                else temp[j] = 1;
            }
            map[i] = temp;
        }
        return map;
    }
    //检查下一位置是否越界
    function checkBor(map, x, y) {
        if (x > 0 && x < map.length && y > 0 && y < map[0].length) return true;
        else return false;
    }
    //检查下一位置是否已经访问
    function checkVal(map, x, y) {
        if (map[x][y] == 1) return true;
        else return false;
    }
    //获取可行的所有下一位置
    function getNext(map, x, y) {
        var next = [];
        if (checkBor(map, x, y + 2) && checkVal(map, x, y + 2)) next.push(0);
        if (checkBor(map, x, y - 2) && checkVal(map, x, y - 2)) next.push(1);
        if (checkBor(map, x + 2, y) && checkVal(map, x + 2, y)) next.push(2);
        if (checkBor(map, x - 2, y) && checkVal(map, x - 2, y)) next.push(3);
        return next;
    }
    //生成迷宫
    function changeMap(map, beginX, beginY) {
        var pos = [[1, 1]];
        map[beginX][beginY] = -1;
        var max = 0;
        dir = [[0, 1], [0, -1], [1, 0], [-1, 0]];
        while (pos.length > 0) {
            x = pos[pos.length - 1][0];
            y = pos[pos.length - 1][1];
            pos.pop();
            while (1) {
                next = getNext(map, x, y);
                if (next.length > 0) {
                    i = next[Math.floor(Math.random() * next.length)];
                    //wx,wy表示墙的位置
                    //nx,ny表示下一位置
                    wx = x + dir[i][0];
                    wy = y + dir[i][1];
                    nx = x + dir[i][0] * 2;
                    ny = y + dir[i][1] * 2;
                    pos.push([nx, ny]);
                    map[wx][wy] = -1;
                    map[nx][ny] = -1;
                    x = nx;
                    y = ny;
                }
                else break;
            }
        }
        return map;
    }
    //绘制迷宫
    function drawMap(map, size) {
        var canvas2 = document.querySelector('#app2 canvas');
        var ctx2 = canvas2.getContext('2d');
        for (i = 0; i < map.length; i++) {
            for (j = 0; j < map[i].length; j++) {
                if (map[i][j] == 0) ctx2.fillStyle = "#555555";
                else ctx2.fillStyle = "#00ff00";
                ctx2.fillRect(i * size, j * size, size, size)

            }
        }
    }
</script>

</html>

最后,祝自己学有所成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值