Exemple #1
0
    /// <summary>
    /// 检查输入
    /// </summary>
    void HandleInput()
    {
        RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);

        if (hit.transform != null)
        {
            switch (activeType)
            {
            case PathCellMark.StartPos:

                BaseCell lastStartCell = CellManager.Instance.GetCellByID(m_StartCellId);
                if (lastStartCell != null)
                {
                    lastStartCell.GetComponent <SpriteRenderer>().color = types[2];
                }

                var startCell = hit.transform.GetComponent <BaseCell>();
                if (startCell != null)
                {
                    m_StartCellId = startCell.ID;
                }

                break;

            case PathCellMark.EndPos:

                BaseCell lastEndCell = CellManager.Instance.GetCellByID(m_EndCellId);
                if (lastEndCell != null)
                {
                    lastEndCell.GetComponent <SpriteRenderer>().color = types[2];
                }

                var endCell = hit.transform.GetComponent <BaseCell>();
                if (endCell != null)
                {
                    m_EndCellId = endCell.ID;
                }
                break;

            case PathCellMark.Block:
                MapManager.Instance.PathFinder.SetBlock(hit.transform.GetComponent <BaseCell>().ID);
                break;

            default:
                break;
            }
            EditCell(gridSystem.GetCellByPos(CellManager.Instance.cellShape, hit.point));
        }
    }
    private void BeamSearch(int startCellId, int endCellId, Action <List <int> > action = null)
    {
        if (!CheckCanSearch(startCellId, endCellId))
        {
            return;
        }

        BaseCell searchingCell = OnSearchStart(startCellId);

        if (searchingCell == null)
        {
            return;
        }

        int openSize = m_BeamWidth;

        if (openSize <= 0)
        {
            openSize = 100;
        }

        bool keepSearching = true;

        while (keepSearching)
        {
            if (searchingCell.ID == endCellId)
            {
                keepSearching = false;
            }
            m_CellsToSearch.Remove(searchingCell);
            m_CellsSearched.Add(searchingCell);
            foreach (BaseCell neighbor in searchingCell.neighbors)
            {
                if (neighbor == null || neighbor.block)
                {
                    continue;
                }
                if (m_CellsSearched.Contains(neighbor) || m_CellsToSearch.Contains(neighbor))
                {
                    continue;
                }

                neighbor.SetParent(searchingCell.ID);
                neighbor.beamFVal = CalF(endCellId, neighbor.ID);

                m_CellsToSearch.Add(neighbor);
                QuicksortListByFVal(ref m_CellsToSearch, 0, m_CellsToSearch.Count - 1);

                while (m_CellsToSearch.Count > openSize)
                {
                    if (needDemonstration)
                    {
                        m_CellsToSearch[m_CellsToSearch.Count - 1].GetComponent <SpriteRenderer>().color = Color.grey;
                    }
                    m_CellsToSearchBackup.Add(m_CellsToSearch[m_CellsToSearch.Count - 1]);
                    m_CellsToSearch.RemoveAt(m_CellsToSearch.Count - 1);
                }

                if (neighbor.ID == endCellId)
                {
                    // 走到了
                    m_Path.Add(neighbor.ID);

                    if (needDemonstration)
                    {
                        neighbor.GetComponent <SpriteRenderer>().color = Color.blue;
                    }

                    BaseCell traceNeighbor = neighbor;
                    int      i             = 0;
                    while (CellManager.Instance.GetCellByID(traceNeighbor.parentID) != null && i < 100)
                    {
                        traceNeighbor = CellManager.Instance.GetCellByID(traceNeighbor.parentID);

                        m_Path.Add(traceNeighbor.ID);

                        if (needDemonstration)
                        {
                            traceNeighbor.GetComponent <SpriteRenderer>().color = Color.blue;
                        }
                        i++;
                    }

                    m_Path.Reverse();
                    OnSearchEnd(action);

                    return;
                }
            }

            // 进入死胡同,找回剪枝剪掉的节点
            if (m_CellsToSearch.Count == 0)
            {
                while (true)
                {
                    if (m_CellsToSearchBackup.Count > 0)
                    {
                        if (m_CellsSearched.Contains(m_CellsToSearchBackup[0]))
                        {
                            m_CellsToSearchBackup.RemoveAt(0);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                if (m_CellsToSearchBackup.Count > 0)
                {
                    QuicksortListByFVal(ref m_CellsToSearchBackup, 0, m_CellsToSearchBackup.Count - 1);
                    Debug.Log("Remove Backup: " + m_CellsToSearchBackup[0].ID);

                    if (needDemonstration)
                    {
                        m_CellsToSearchBackup[0].GetComponent <SpriteRenderer>().color = Color.magenta;
                    }
                    m_CellsToSearch.Add(m_CellsToSearchBackup[0]);
                    m_CellsToSearchBackup.RemoveAt(0);
                }
                else
                {
                    Debug.Log("Open列表为空,搜索结束");
                    break;
                }
            }
            searchingCell = m_CellsToSearch[0];
            if (searchingCell == null)
            {
                Debug.Log("找不到下一个搜索节点,搜索结束");
                break;
            }

            if (needDemonstration)
            {
                searchingCell.GetComponent <SpriteRenderer>().color = Color.yellow;
            }
        }
    }
    private void AStarSearch(int startCellId, int endCellId, Action <List <int> > action = null)
    {
        if (!CheckCanSearch(startCellId, endCellId))
        {
            return;
        }

        BaseCell searchingCell = OnSearchStart(startCellId);

        if (searchingCell == null)
        {
            return;
        }

        bool keepSearching = true;

        while (keepSearching)
        {
            if (searchingCell.ID == endCellId)
            {
                keepSearching = false;
            }
            m_CellsToSearch.Remove(searchingCell);
            m_CellsSearched.Add(searchingCell);

            foreach (BaseCell neighbor in searchingCell.neighbors)
            {
                if (neighbor == null || neighbor.block)
                {
                    continue;
                }
                if (m_CellsToSearch.Contains(neighbor) || m_CellsSearched.Contains(neighbor))
                {
                    continue;
                }
                m_CellsToSearch.Add(neighbor);
                neighbor.SetParent(searchingCell.ID);
                if (neighbor.ID == endCellId)
                {
                    // 走到了
                    m_Path.Add(neighbor.ID);
                    if (needDemonstration)
                    {
                        neighbor.GetComponent <SpriteRenderer>().color = Color.blue;
                    }

                    BaseCell traceNeighbor = neighbor;
                    int      i             = 0;
                    while (CellManager.Instance.GetCellByID(traceNeighbor.parentID) != null && i < 100)
                    {
                        traceNeighbor = CellManager.Instance.GetCellByID(traceNeighbor.parentID);

                        if (needDemonstration)
                        {
                            traceNeighbor.GetComponent <SpriteRenderer>().color = Color.blue;
                        }

                        m_Path.Add(traceNeighbor.ID);
                        i++;
                    }

                    m_Path.Reverse();

                    OnSearchEnd(action);

                    return;
                }
            }

            BaseCell newSearchingCell = null;
            int      minF             = -1;
            foreach (var cell in m_CellsToSearch)
            {
                int f = CalF(endCellId, cell.ID);
                if (f < 0)
                {
                    Debug.Log("这货距离小于零啊,有问题");
                    continue;
                }
                else if (f <= minF || minF < 0)
                {
                    minF             = f;
                    newSearchingCell = cell;
                }
            }

            if (m_CellsToSearch.Count == 0)
            {
                Debug.Log("Open列表为空,搜索结束");
                break;
            }
            if (newSearchingCell == null)
            {
                Debug.Log("找不到下一个搜索节点,搜索结束");
                break;
            }

            if (needDemonstration)
            {
                newSearchingCell.GetComponent <SpriteRenderer>().color = Color.yellow;
            }
            searchingCell = newSearchingCell;
        }
    }
    // TODO: 路径标记有问题,非最短路径
    private void BfsSearch(int startCellId, int endCellId, Action <List <int> > action = null)
    {
        if (!CheckCanSearch(startCellId, endCellId))
        {
            return;
        }

        BaseCell searchingCell = OnSearchStart(startCellId);

        if (searchingCell == null)
        {
            return;
        }

        bool keepSearching = true;

        while (keepSearching)
        {
            foreach (BaseCell neighbor in searchingCell.neighbors)
            {
                if (neighbor == null || neighbor.block)
                {
                    continue;
                }
                if (m_CellsSearched.Contains(neighbor))
                {
                    continue;
                }
                neighbor.SetParent(searchingCell.ID);

                if (neighbor.ID == endCellId)
                {
                    // 走到了

                    m_Path.Add(neighbor.ID);

                    if (needDemonstration)
                    {
                        neighbor.GetComponent <SpriteRenderer>().color = Color.blue;
                    }

                    BaseCell traceNeighbor = neighbor;
                    int      i             = 0;
                    while (CellManager.Instance.GetCellByID(traceNeighbor.parentID) != null && i < 100)
                    {
                        Debug.Log(traceNeighbor.parentID);
                        traceNeighbor = CellManager.Instance.GetCellByID(traceNeighbor.parentID);

                        m_Path.Add(traceNeighbor.ID);
                        if (needDemonstration)
                        {
                            traceNeighbor.GetComponent <SpriteRenderer>().color = Color.blue;
                        }
                        i++;
                    }

                    m_Path.Reverse();

                    OnSearchEnd(action);
                    return;
                }
                if (!m_CellsSearched.Contains(neighbor) && !m_CellsToSearch.Contains(neighbor))
                {
                    m_CellsToSearch.Add(neighbor);

                    if (needDemonstration)
                    {
                        neighbor.GetComponent <SpriteRenderer>().color = Color.yellow;
                    }
                }
            }
            m_CellsToSearch.Remove(searchingCell);
            m_CellsSearched.Add(searchingCell);
            if (m_CellsToSearch.Count == 0)
            {
                break;
            }
            searchingCell = m_CellsToSearch[0];
            m_CellsToSearch.RemoveAt(0);
        }
    }