美文网首页
html版a*算法实现自动寻路简单demo

html版a*算法实现自动寻路简单demo

作者: littlesunn | 来源:发表于2023-01-22 16:03 被阅读0次
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <div class="big-bg" id="bg">
            <div id="role">
                <img src="" alt="" width="40" id="arrow">
            </div>
        </div>
    </body>
    
    </html>
    
    <script>
        let unit = 40; // 一个单位的长度,就是一个网格的宽高
        let coordList = [];  // 路径点集合
        let originNode = {};  // 起点
        let targetNode = {};  // 终点
        let xxx = [
            {x: 12,y:12},
            {x: 12,y:12},
            {x: 12,y:12},
        ];
        let targetCell = null;
        let timer = null;
    
        var bg = document.getElementById("bg")
        for (let index = 0; index < 2000; index++) {
            var cell = document.createElement("div");
            cell.classList.add("cell")
            bg.appendChild(cell)
        }
    
        // 获取起点
        let startCell = document.getElementById("role");
    
        // 点击的点定为终点
        document.addEventListener("mousedown", (e) => {
            let { x: x1, y: y1 } = startCell.getBoundingClientRect();
            originNode = {
                x: x1 / unit,
                y: y1 / unit,
            }
    
            let { x: x2, y: y2 } = e.target.getBoundingClientRect();
            targetNode = {
                x: x2 / unit,
                y: y2 / unit,
            }
            targetCell = e.target;
            targetCell.style.backgroundColor = "#fff566"
            pushNearNode()
        })
    
        function getNearNodes(originNode) {
            let leftNode = {
                name: "left",
                x: originNode.x - 1,
                y: originNode.y,
                g: 1,  // 附近点的距离,水平垂直边是定义为1个单位,斜边定义为1.4个的单位(暂时不考虑斜边)
                h: 0,  // 这点距离终点的水平距离x个单位 与 这点距离终点的垂直距离x个单位 之和
                f: 0,  // g 与 h 之和
            };
            setDistProp(leftNode);
    
            let topNode = {
                name: "top",
                x: originNode.x,
                y: originNode.y - 1,
                g: 1,
                h: 0,
                f: 0,
            };
            setDistProp(topNode);
    
            let rightNode = {
                name: "right",
                x: originNode.x + 1,
                y: originNode.y,
                g: 1,
                h: 0,
                f: 0,
            };
            setDistProp(rightNode);
    
            let bottomNode = {
                name: "bottom",
                x: originNode.x,
                y: originNode.y + 1,
                g: 1,
                h: 0,
                f: 0,
            };
            setDistProp(bottomNode);
            return [leftNode, topNode, rightNode, bottomNode,]
        }
    
        function setDistProp(node) {
            if (!node.g) {
                node.g = 0;
            }
            node.h = Math.abs(targetNode.x - node.x) + Math.abs(targetNode.y - node.y);
            node.f = node.g + node.h;
        }
    
        // 递归找离目标点最近的点,push到数组当中
        function pushNearNode() {
            let nearNodeArr = getNearNodes(originNode);
            let minFNode = null;   // 离目标最近的点
            for (let index = 0; index < nearNodeArr.length; index++) {
                const node = nearNodeArr[index];
                if (!minFNode) {
                    minFNode = node;
                } else if (node.f <= minFNode.f) {
                    minFNode = node;
                }
            }
            if (minFNode) {
                coordList.push(minFNode);
                originNode = minFNode;
    
                if (minFNode.x == targetNode.x && minFNode.y == targetNode.y) {  // 到达终点
                    coordList.push(targetNode);
                    let step = 0;
                    timer = setInterval(() => {
                        if (coordList[step]) {
                            startCell.style.left = coordList[step].x * unit + "px";
                            startCell.style.top = coordList[step].y * unit + "px";
                            switch (coordList[step].name) {
                                case "bottom":
                                    startCell.style.transform = "rotate(0)"
                                    break;
                                case "right":
                                    startCell.style.transform = "rotate(-90deg)"
                                    break;
                                case "left":
                                    startCell.style.transform = "rotate(90deg)"
                                    break;
                                case "top":
                                    startCell.style.transform = "rotate(-180deg)"
                                    break;
                                default:
                                    break;
                            }
                            console.log(coordList[step], "coordList[step]");
                            step++;
                        } else {
                            targetCell.style.backgroundColor = "transparent";
                            coordList = []
                            clearInterval(timer);
                        }
                    }, 200)
                } else {
                    pushNearNode();
                }
            }
        }
    
    </script>
    
    <style>
        * {
            box-sizing: border-box;
        }
    
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    
        #role {
            width: 40px;
            height: 40px;
            left: 680px;
            top: 80px;
            position: fixed;
            background: linear-gradient(to bottom, #bae0ff, #1677ff);
            transition: .3s;
            display: flex;
            justify-content: center;
            align-items: center;
        }
    
        .big-bg {
            width: 100vw;
            height: 100vh;
            background: #152439;
            display: flex;
            flex-wrap: wrap;
            position: relative;
        }
    
        .cell {
            width: 40px;
            height: 40px;
            border-bottom: 1px solid rgba(33, 233, 252, 0.12);
            border-right: 1px solid rgba(33, 233, 252, 0.12);
        }
    
        .cell:hover {
            background-color: rgba(33, 233, 252, 0.22);
        }
    
        .obstacle {
            background-color: #f5222d;
            color: #fff;
            font-size: 14px;
            line-height: 19px;
            text-align: center;
        }
    </style>
    

    思路讲解在b站: https://www.bilibili.com/video/BV1fv4y1r7sE/

    相关文章

      网友评论

          本文标题:html版a*算法实现自动寻路简单demo

          本文链接:https://www.haomeiwen.com/subject/gbbkhdtx.html