js寻路算法

f()=g()+h();    //g为每个节点到起点得距离;h为每个节点到终点得距离。两个距离通过勾股定理可以算出;

以下代码基本的解释和注释都有。不懂得可以留言哦

css

<style>
        ul{
            list-style: none;
            margin: 0;
            padding: 0;
            border: 1px solid #f5f5f5;
            border-right: none;
            border-bottom: none;
            
            margin: 100px auto;
        }
        ul li{
            float: left;
            border: solid 1px #f5f5f5;
            border-left: none;
            border-top: none;
            display: inline-block;
            background: black;
        }
        .start{
            background: skyblue;
        }
        .end{
            background: green;
        }
        .usual{
            background: pink;
        }
</style>

 

 html

<body>
    <ul id="map-ul"></ul>
    <input id="btn" type="button" value="开始" />
</body>

js

<script>
    var oUl = document.getElementById("map-ul");
    var startBtn = document.getElementById("btn");
    var Li = oUl.getElementsByTagName("li");
    var beginLi = document.getElementsByClassName("start");
    var endLi = document.getElementsByClassName("end");
    var map = [
    1,1,1,1,1,1,1,1,1,1,//0为起点;2为障碍物,3为终点
    1,1,0,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,2,2,2,1,1,
    1,1,1,1,1,2,1,1,1,1,
    1,1,1,1,1,2,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,3,
    1,1,1,1,1,1,1,1,1,1
    ];
    var openArr = [];//可能要走的路线
    var closeArr = [];//已经关闭的路线
    var cols = Math.sqrt(map.length)
    var sizeBox = 20;
    //初始化
    init()
    function init(){
        creatMap();//初始化地图
        startBtn.onclick = function(){
            openFn();
        }
    }
    function creatMap(){
        
        oUl.style.width = cols * (sizeBox + 1) + 1 + "px";
        oUl.style.height = cols * (sizeBox + 1) + 1 + "px";
        for (var i=0;i<map.length;i++) {
            var oLi = document.createElement("li");
            oLi.style.width = sizeBox + "px";
            oLi.style.height = sizeBox + "px";
            oUl.appendChild(oLi)
            if (map[i] == 2) {
                oLi.className = "usual"
                closeArr.push(oLi)//障碍物添加到关闭得线路
            } else if(map[i] == 0){
                oLi.className = "start"
                openArr.push(oLi)//起始点添加到要走得线路 
            }else if(map[i] == 3){
                oLi.className = "end"
            }
        }
    }
    function f(nodeLi){//nodeLi每个li节点
        return g(nodeLi) + h(nodeLi);//g为节点到初始位置的距离,h为节点到结束位置的距离
    }
    function g(nodeLi){
        //勾股定理算出距离
        var x = beginLi[0].offsetLeft - nodeLi.offsetLeft;
        var y = beginLi[0].offsetTop - nodeLi.offsetTop;
        return Math.sqrt(x*x+y*y);
    }
    function h(nodeLi){
        var x = endLi[0].offsetLeft - nodeLi.offsetLeft;
        var y = endLi[0].offsetTop - nodeLi.offsetTop;
        return Math.sqrt(x*x+y*y);
    }
    function openFn(){
        //以起始位置为可能要走的第一个Li
        var nowLi = openArr.shift();
        if(nowLi == endLi[0]){
            showLine();
            
            return;
        }
        closeFn(nowLi);//将找过得节点添加到关闭的路线
        findLi(nowLi);//寻找第一个Li周围的可能要走的Li
        openArr.sort(function(li1,li2){//将可能走得线路得节点通过距离从下到大排序。当下次循环得时候可以直接拿到上个最近得节点,
            return li1.num - li2.num;
        })
        
        openFn();
    }
    function findLi(nowLi){
        var result = [];//所有没走过的路线。去除closeArr里存在的路线
        for (var i=0;i<Li.length;i++) {
            if( filter(Li[i])){
                result.push(Li[i])
            }
        }
        function filter(Li){//如果closeArr里没有就添加到队列
            for (var i=0;i<closeArr.length;i++) {
                if(closeArr[i] == Li){
                    return false;
                }
            }
            for (var i=0;i<openArr.length;i++) {
                if(openArr[i] == Li){
                    
                    return false;
                }
            }
            return true;
        }
        //在所有没走过的节点找到与当前节点相邻的8个方向的节点
        for(var i=0;i<result.length;i++){
            if(Math.abs(nowLi.offsetLeft - result[i].offsetLeft)<=21&&Math.abs(nowLi.offsetTop - result[i].offsetTop)<=21){
                result[i].num = f(result[i]);
                result[i].parent = nowLi;//设置指针
                openArr.push(result[i])
            }
        }
    }
    function showLine(){
        var result = [];
        var lastLi = closeArr.pop();
        var iNow = 0;
        findParent(lastLi);
        function findParent(li){
            result.unshift(li);
            if( li.parent == beginLi[0] ){
                return;
            }
            findParent(li.parent);//通过指针递归
            console.log(li.parent)
        }
        for (var i=0;i<result.length;i++) {
            result[i].style.backgroundColor = "plum";
        }
    }
    function closeFn(nowLi){
        closeArr.push(nowLi);
    }
</script>

 

    

 

posted @ 2018-06-21 20:48  AINIJJ  阅读(437)  评论(0编辑  收藏  举报