예제 #1
0
파일: Form1.cs 프로젝트: choi98772/pathtest
        CUnit[] mUnits = null;                  //화면에 표시되는 유닛들


        public Form1()
        {
            InitializeComponent();
            InitializeComponent2();

            mNavigationData = new CNavigationData();
            mAStar          = new CAStarPathFinding();

            mUnits = new CUnit[MAX_UNIT];

            for (int i = 0; i < MAX_UNIT; ++i)
            {
                mUnits[i] = new CUnit();

                if (i == 0)
                {
                    //가정 첫번째 유닛을 추적자로 설정
                    mUnits[i].EnableTracking(true);
                    //m_pUnits[i].StartTracking(true);  //주석을 해제 하면 자동 추적한다
                }
                else
                {
                    mUnits[i].EnableTracking(false);
                    mUnits[i].SetTarget(mUnits[0]);
                }
            }
        }
예제 #2
0
파일: Form1.cs 프로젝트: choi98772/pathtest
        public Form1()
        {
            InitializeComponent();
            InitializeComponent2();
            m_ND          = new CNavigationData();
            m_PathFinding = new CAStarPathFinding();

            m_pUnits = new CUnit[MAX_UNIT];

            Random rnd = new Random();

            for (int i = 0; i < MAX_UNIT; ++i)
            {
                m_pUnits[i] = new CUnit();

                if (i == 0)
                {
                    m_pUnits[i].EnableTracking(true);
                    //m_pUnits[i].StartTracking(true);  //주석을 해제 하면 자동 추적한다
                }
                else
                {
                    m_pUnits[i].EnableTracking(false);
                    m_pUnits[i].SetTarget(m_pUnits[0]);
                }
            }
        }
예제 #3
0
 public void RandomPos(CNavigationData ND)
 {
     while (true)
     {
         int cx = m_RND.Next(ND.GetWidth());
         int cy = m_RND.Next(ND.GetHeight());
         if (ND.IsValidPos(cx, cy))
         {
             m_iPos[0] = cx;
             m_iPos[1] = cy;
             break;
         }
     }
 }
예제 #4
0
파일: CUnit.cs 프로젝트: choi98772/pathtest
        //맵에서 임의의 위치를 선택해서 현재위치를 설정하기
        public void RandomPos(CNavigationData ND)
        {
            //유효한 임의의 위치를 구할때까지 반복
            while (true)
            {
                //임의의 위치를 구하고
                int cx = m_RND.Next(ND.GetWidth());
                int cy = m_RND.Next(ND.GetHeight());

                //해당 위치가 이동가능한 위치면, 유닛 좌표를 해당위치로 설정한후 while 종료
                if (ND.IsValidPos(cx, cy))
                {
                    m_iPos[0] = cx;
                    m_iPos[1] = cy;
                    break;
                }
            }
        }
예제 #5
0
        public void Update(CNavigationData ND, CAStarPathFinding FF)
        {
            if (!m_bMove)
            {
                if (m_Target != null)
                {//
                    int dx = m_iPos[0] - m_Target.GetX();
                    int dy = m_iPos[1] - m_Target.GetY();

                    if (m_bTracking)
                    {//타겟을 추적하는 모드라면
                        if (m_bStartTracking)
                        {
                            if (Math.Abs(dx) > 3 || Math.Abs(dy) > 3)
                            {
                                CNaviNode pStart = CNaviNode.Create(m_iPos[0], m_iPos[1]);
                                CNaviNode pEnd   = CNaviNode.Create(m_Target.GetX(), m_Target.GetY());
                                m_vecPath = new List <CNaviNode>();
                                if (!FF.FindPath(pStart, pEnd, ref m_vecPath, ND))
                                {
                                }
                                else
                                {
                                    m_bMove = true;
                                }
                            }
                        }
                    }
                    else
                    {//타겟을 회피하는 모드다
                        if (Math.Abs(dx) < 4 && Math.Abs(dy) < 4 && !m_bMove)
                        {
                            while (true)
                            {
                                int cx = m_RND.Next(ND.GetWidth());
                                int cy = m_RND.Next(ND.GetHeight());
                                if (ND.IsValidPos(cx, cy))
                                {
                                    m_vecPath = new List <CNaviNode>();
                                    CNaviNode pStart = CNaviNode.Create(m_iPos[0], m_iPos[1]);
                                    CNaviNode pEnd   = CNaviNode.Create(cx, cy);
                                    if (!FF.FindPath(pStart, pEnd, ref m_vecPath, ND))
                                    {
                                        continue;
                                    }
                                    else
                                    {
                                        m_bMove = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                if (m_vecPath == null)
                {
                    m_bMove = false;
                }
                else
                {
                    int curindex = m_vecPath.Count - 1;
                    if (curindex < 0)
                    {
                        m_bMove   = false;
                        m_vecPath = null;
                    }
                    else
                    {
                        m_iPos[0] = m_vecPath[curindex].x;
                        m_iPos[1] = m_vecPath[curindex].y;
                        m_vecPath.RemoveAt(curindex);
                    }
                }
            }
        }
예제 #6
0
        //시작 위치 PStart에서 목표위치 pEnd까지의 경로를 구한다. 경로가 구해진경우 true그렇지 않은경우 fale
        //finalPath : 구해진경로
        //navigation : 지형데이터를 제공한다
        public bool FindPath(CNaviNode startPos, CNaviNode endPos, ref List <CNaviNode> finalPath, CNavigationData navigation)
        {
            Delete();

            CNaviNode currentNode = startPos.Clone();

            /*
             * insert start position to open node, 시작점을 열린노드에 삽입한다.
             * */
            mOpenNode.Add(currentNode);

            int depth = 0;

            currentNode.depth = depth;

            List <CNaviNode> childs;

            childs = new List <CNaviNode>();

            while (true)
            {
                if (mOpenNode.Count == 0)
                {                //if opennode has not contents, it's meaning that path not found. 만일 열린노드에 더이상 데이터가 없다면 길이 존재하지 않는것이다.
                    break;
                }



                currentNode = mOpenNode[0];                    //get first content, 열린노드의 가장처음항목을 하나 가져온다

                mOpenNode.RemoveAt(0);                         //delete content from open node, 가져온것은 열린노드에서 제거한다

                if (endPos.IsSamePos(currentNode))             //if that node is end position, we found path, 만일 가져온 노드가 목표점이라면 해당 노드를 패스목록에 추가하고 길탐색을 종료한다
                {
                    while (currentNode != null)                //tracking it's parent node for it's parent is null
                    {
                        finalPath.Add(currentNode);            //add node to path list
                        currentNode = currentNode.GetParent(); //get current node's parent
                    }

                    return(true);
                }

                currentNode = InsertCloseNode(currentNode); //insert current node to close list, 목표점이 아니면 해당 노드를 닫힌노드에 삽입한다.


                ++depth; //탐색깊이를 하나 증가 시킨다

                childs.Clear();

                navigation.GetNeighbor(currentNode, ref childs);    //해당노드의 인접한 노드들을 모두 가져와서

                for (int i = 0; i < childs.Count; ++i)
                {
                    if (FindFromCloseNode(childs[i]))                        //만일 닫힌노드에 있는것이면 무시하고
                    {
                        continue;
                    }

                    //닫힌노드에 없는것이라면, 거리를 구한다음에 열린노드에 삽입한다.
                    childs[i].CalcDist(endPos, depth);
                    childs[i].SetParent(currentNode);
                    InsertOpenNode(childs[i]);
                }

                //열린노드를 비용에 따라서 정렬한다
                SortOpenNode();
            }

            Delete();
            return(false);
        }
예제 #7
0
파일: CUnit.cs 프로젝트: choi98772/pathtest
        //매프레임 호출되어 유닛을 이동시킴
        public void Update(CNavigationData ND, CAStarPathFinding FF)
        {
            //현재 이동중이지 않을 경우
            if (!m_bMove)
            {
                //묙표유닛이 존재한다면
                if (m_Target != null)
                {//
                    //묙표유닛과 자신과의 거리를 구한다
                    int dx = m_iPos[0] - m_Target.GetX();
                    int dy = m_iPos[1] - m_Target.GetY();

                    if (m_bTracking)
                    {//타겟을 자동추적하는 모드라면
                        //추적중이라면
                        if (m_bStartTracking)
                        {
                            //목표와의 거리가 3셀이상이면
                            if (Math.Abs(dx) > 3 || Math.Abs(dy) > 3)
                            {
                                //나의 위치를 시작점, 목표위치를 끝점으로해서
                                CNaviNode pStart = CNaviNode.Create(m_iPos[0], m_iPos[1]);
                                CNaviNode pEnd   = CNaviNode.Create(m_Target.GetX(), m_Target.GetY());

                                //경로를 구하고
                                m_vecPath = new List <CNaviNode>();
                                if (!FF.FindPath(pStart, pEnd, ref m_vecPath, ND))
                                {
                                }
                                else
                                {
                                    //경로가 구해졌으면 유닛이동을 활성화
                                    m_bMove = true;
                                }
                            }
                        }
                    }
                    else
                    {//타겟을 회피하는 모드다
                        //목표와의 거리가 4셀 이하이고, 현재 이동중이지 않으면
                        if (Math.Abs(dx) < 4 && Math.Abs(dy) < 4 && !m_bMove)
                        {
                            //무한반복
                            while (true)
                            {
                                //맵에서 임의의 위치를 하나 선택하고
                                int cx = m_RND.Next(ND.GetWidth());
                                int cy = m_RND.Next(ND.GetHeight());

                                //해당 위치가 이동가능한곳이면
                                if (ND.IsValidPos(cx, cy))
                                {
                                    //유닛의 현재 위치를 시작점, 위에서 선택한 임의의 위치를 끝점으로 해서
                                    CNaviNode pStart = CNaviNode.Create(m_iPos[0], m_iPos[1]);
                                    CNaviNode pEnd   = CNaviNode.Create(cx, cy);

                                    //경로를 구하고
                                    m_vecPath = new List <CNaviNode>();
                                    if (!FF.FindPath(pStart, pEnd, ref m_vecPath, ND))
                                    {
                                        //경로가 구해지지 않았으면 while 루프를 다시 반복
                                        continue;
                                    }
                                    else
                                    {
                                        //경로가 구해졌으면 유닛을 이동상태로 설정하고, while 루프를 종료
                                        m_bMove = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else //유닛이 현재 이동중인경우면
            {
                //경로가 존재하지 않으면, 이동모드를 중지
                if (m_vecPath == null)
                {
                    m_bMove = false;
                }
                else
                {
                    int curindex = m_vecPath.Count - 1;

                    //경로의 목표점에 도달했으면
                    if (curindex < 0)
                    {
                        //이동모드를 중지하고, 경로는 클리어
                        m_bMove   = false;
                        m_vecPath = null;
                    }
                    else
                    {
                        //경로의 현재 점을 유닛의 위치로 설정하고, 사용한 좌표는 경로 목록에서 제거하기
                        m_iPos[0] = m_vecPath[curindex].x;
                        m_iPos[1] = m_vecPath[curindex].y;
                        m_vecPath.RemoveAt(curindex);
                    }
                }
            }
        }