private void DoFindPath()
    {
        OpenStartNode();

        while (!_openedList.isEmpty)
        {
            AStarEightDirectionsHeapNode currentNode = _openedList.GetMinimumCostNode();

            if (IsDestination(currentNode))
            {
                break;
            }

            OpenNode(currentNode, Vector2.up);
            OpenNode(currentNode, new Vector2(1, 1));
            OpenNode(currentNode, Vector2.right);
            OpenNode(currentNode, new Vector2(1, -1));
            OpenNode(currentNode, Vector2.down);
            OpenNode(currentNode, new Vector2(-1, -1));
            OpenNode(currentNode, Vector2.left);
            OpenNode(currentNode, new Vector2(-1, 1));

            CloseNode(currentNode);
        }
    }
    void OpenNode(AStarEightDirectionsHeapNode currentNode, Vector2 direction)
    {
        AStarEightDirectionsHeapNode newNode = GetNode(currentNode, direction);

        if (newNode == null || !newNode.canThrough)
        {
            return;                                                             //如果没获取到新节点或新节点不能通行则直接return
        }
        switch (newNode.state)
        {
        case AStarEightDirectionsNodeState.unopened:
            DoOpenNode(currentNode, newNode);
            break;

        case AStarEightDirectionsNodeState.opened:
            if (currentNode.startToCost < newNode.nextNode.startToCost)         //如果新节点已经开了但从起点到指向的节点的成本比当前节点高
            {
                ReopenNode(currentNode, newNode);
            }
            break;

        case AStarEightDirectionsNodeState.closed:
            break;
        }
    }
 public void Reset()     //寻路开始时清空成本和指向
 {
     _state       = AStarEightDirectionsNodeState.unopened;
     _nextNode    = null;
     _startToCost = 0;
     _toEndCost   = 0;
     _totalCost   = 0;
 }
    void OpenStartNode()
    {
        AStarEightDirectionsHeapNode startNode = GetNode(_startPosition);

        startNode.Open(_endPosition);

        _openedList.Set(startNode);
    }
    public void Remove(AStarEightDirectionsHeapNode node)
    {
        var targetSubHeap = _heap.FindFirstThroughValue(node.totalCost);

        targetSubHeap.RemoveFirstThroughObj(node);

        if (targetSubHeap.Count == 0)
        {
            _heap.RemoveFirstThroughObj(targetSubHeap);
        }
    }
Esempio n. 6
0
    Color GetNodeColor(AStarEightDirectionsHeapNode node, float maxStartToCost, float maxToEndCost)
    {
        if (!node.canThrough)
        {
            return(Color.black);
        }

        Color nodeRed  = Color.red * node.startToCost / maxStartToCost;
        Color nodeBlue = Color.blue * node.toEndCost / maxToEndCost;

        return(nodeRed + nodeBlue + Color.gray * 0.5f);
    }
    public void Set(AStarEightDirectionsHeapNode node)
    {
        MinBinaryHeap <AStarEightDirectionsHeapNode> subHeap = _heap.FindFirstThroughValue(node.totalCost);

        if (subHeap != null)
        {
            subHeap.SetNode(node, node.toEndCost);
        }
        else
        {
            subHeap = new MinBinaryHeap <AStarEightDirectionsHeapNode>();
            subHeap.SetNode(node, node.toEndCost);

            _heap.SetNode(subHeap, node.totalCost);
        }
    }
Esempio n. 8
0
    void DisplayPath()
    {
        AStarEightDirectionsHeapNode currentNode = _aStar.GetNode(_endPosition);

        if (currentNode == null || currentNode.nextNode == null)
        {
            return;
        }

        while (currentNode.nextNode != null)
        {
            AddGreen(currentNode);

            currentNode = currentNode.nextNode;
        }

        AddGreen(currentNode);
    }
Esempio n. 9
0
    string GetDirectionText(AStarEightDirectionsHeapNode node)
    {
        if (node == null || node.nextNode == null)
        {
            return("");
        }

        Vector2 direction = node.nextNode.position - node.position;

        if (direction == Vector2.up)
        {
            return("↑");
        }
        if (direction == Vector2.right)
        {
            return("→");
        }
        if (direction == Vector2.down)
        {
            return("↓");
        }
        if (direction == Vector2.left)
        {
            return("←");
        }
        if (direction == new Vector2(-1, -1))
        {
            return("↙");
        }
        if (direction == new Vector2(-1, 1))
        {
            return("↖");
        }
        if (direction == new Vector2(1, -1))
        {
            return("↘");
        }
        if (direction == new Vector2(1, 1))
        {
            return("↗");
        }

        return("");
    }
    public void Pathfind_CanFind_NoObstacle()
    {
        AStarEightDirections aStar = new AStarEightDirections(7, 7);

        Vector2 startPosition = new Vector2(0, 0);
        Vector2 endPosition   = new Vector2(6, 6);

        aStar.FindPath(startPosition, endPosition);

        /*
         *  0   0   0   0   ↘   ↓   E
         *
         *  0   0   0   ↘   ↓   ↙   ←
         *
         *  0   0   ↘   ↓   ↙   ←   ↖
         *
         *  0   ↘   ↓   ↙   ←   ↖   0
         *
         *  ↘   ↓   ↙   ←   ↖   0   0
         *
         *  ↓   ↙   ←   ↖   0   0   0
         *
         *  S   ←   ↖   0   0   0   0
         */
        AStarEightDirectionsHeapNode[,] matrix    = aStar.matrix;
        AStarEightDirectionsHeapNode[,] nextNodes = new AStarEightDirectionsHeapNode[7, 7]
        {
            { null, matrix[0, 0], matrix[1, 1], null, null, null, null },
            { matrix[0, 0], matrix[0, 0], matrix[1, 1], matrix[2, 2], null, null, null },
            { matrix[1, 1], matrix[1, 1], matrix[1, 1], matrix[2, 2], matrix[3, 3], null, null },
            { null, matrix[2, 2], matrix[2, 2], matrix[2, 2], matrix[3, 3], matrix[4, 4], null },
            { null, null, matrix[3, 3], matrix[3, 3], matrix[3, 3], matrix[4, 4], matrix[5, 5] },
            { null, null, null, matrix[4, 4], matrix[4, 4], matrix[4, 4], matrix[5, 5] },
            { null, null, null, null, matrix[5, 5], matrix[5, 5], matrix[5, 5] }
        };
        for (int x = 0; x < 7; x++)
        {
            for (int y = 0; y < 7; y++)
            {
                Assert.AreEqual(nextNodes[y, x], aStar.matrix[x, y].nextNode);      //二维数组赋值是按照横竖x的方式进行的,也就是说上面的矩阵写错了,要转置,这就是一个用 [y, x] 一个用 [x, y] 的原因
            }
        }
    }
    public AStarEightDirections(int width, int height)
    {
        if (width < 0)
        {
            width = 0;                              //防止传入负数
        }
        if (height < 0)
        {
            height = 0;                             //防止传入负数
        }
        _matrix = new AStarEightDirectionsHeapNode[width, height];

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                _matrix[x, y] = new AStarEightDirectionsHeapNode(x, y);
            }
        }
    }
Esempio n. 12
0
    void MouseMiddleDown()
    {
        Vector2 position = GetMousePosition();

        AStarEightDirectionsHeapNode node = _aStar.GetNode(position);

        if (node == null)
        {
            return;
        }

        if (node.canThrough)
        {
            _aStar.SetObstacle(position);
        }
        else
        {
            _aStar.RemoveObstacle(position);
        }

        DoFindPath();
    }
    void ReopenNode(AStarEightDirectionsHeapNode currentNode, AStarEightDirectionsHeapNode openNode)
    {
        _openedList.Remove(openNode);

        DoOpenNode(currentNode, openNode);
    }
 bool IsDestination(AStarEightDirectionsHeapNode currentNode)
 {
     return(currentNode == GetNode(_endPosition));
 }
Esempio n. 15
0
    void AddGreen(AStarEightDirectionsHeapNode currentNode)
    {
        Vector2 position = currentNode.position;

        _displayMatrix[(int)position.x, (int)position.y].GetComponentInChildren <Image>().color += Color.green;
    }
    void DoOpenNode(AStarEightDirectionsHeapNode currentNode, AStarEightDirectionsHeapNode openNode)
    {
        openNode.Open(currentNode, _endPosition);

        _openedList.Set(openNode);
    }
 void CloseNode(AStarEightDirectionsHeapNode node)
 {
     _openedList.Remove(node);
     node.Close();
 }
Esempio n. 18
0
 void DisplayANode(AStarEightDirectionsHeapNode node, GameObject displayer, float maxStartToCost, float maxToEndCost)
 {
     displayer.GetComponentInChildren <Image>().color = GetNodeColor(node, maxStartToCost, maxToEndCost);
     displayer.GetComponentInChildren <Text>().text   = GetDirectionText(node);
 }
 public void Open(AStarEightDirectionsHeapNode nextNode, Vector2 destination)
 {
     _state    = AStarEightDirectionsNodeState.opened;
     _nextNode = nextNode;
     ComputeCost(destination);
 }
 public AStarEightDirectionsHeapNode GetNode(AStarEightDirectionsHeapNode node, Vector2 direction)
 {
     return(GetNode(node.position + direction));
 }