Esempio n. 1
0
        //마우스 버튼이 눌린경우
        protected override void OnMouseDown(MouseEventArgs e)
        {
            //어느셀이 선택되었는지 확인하기
            int cx = e.X / CELL_SIZE;
            int cy = e.Y / CELL_SIZE;

            base.OnMouseDown(e);

            if (mAStar != null)
            {
                for (int i = 0; i < MAX_UNIT; ++i)
                {
                    //추적중인 유닛이면
                    if (mUnits[i].IsTracking())
                    {
                        //유닛의 현재위치를 시작지점으로
                        CNaviNode pStart = CNaviNode.Create(mUnits[i].GetX(), mUnits[i].GetY());

                        //마우스로 클릭한 지점의 셀 위치를 끝지점으로
                        CNaviNode pEnd = CNaviNode.Create(cx, cy);

                        List <CNaviNode> vecPath = new List <CNaviNode>();

                        //경로룰 구해서 구해지면 유닛에 설정해주기
                        if (mAStar.FindPath(pStart, pEnd, ref vecPath, mNavigationData))
                        {
                            //경로가 구해지면 경로를 유닛에 설정해주기
                            mUnits[i].SetPath(vecPath);
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        //해당 노드에 인접한 이동가능한 이웃노드들을 모두구한다, 리턴값은 이웃의 개수
        virtual public int GetNeighbor(CNaviNode pos, ref List <CNaviNode> vecList)
        {
            int[] distx = new int[3] {
                -1, 0, 1
            };
            int[] disty = new int[3] {
                -1, 0, 1
            };

            for (int y = 0; y < 3; ++y)
            {
                for (int x = 0; x < 3; ++x)
                {
                    int cx = distx[x] + pos.x;
                    int cy = disty[y] + pos.y;
                    if (cx == pos.x && cy == pos.y)
                    {
                        continue;
                    }

                    if (!IsValidPos(cx, cy))
                    {
                        continue;
                    }
                    vecList.Add(CNaviNode.Create(cx, cy));
                }
            }

            return(vecList.Count);
        }
Esempio n. 3
0
        protected override void OnMouseDown(MouseEventArgs e)
        {
            int cx = e.X / 16;
            int cy = e.Y / 16;

            base.OnMouseDown(e);

            if (m_PathFinding != null)
            {
                for (int i = 0; i < MAX_UNIT; ++i)
                {
                    if (m_pUnits[i].IsTracking())
                    {
                        CNaviNode        pStart  = CNaviNode.Create(m_pUnits[i].GetX(), m_pUnits[i].GetY());
                        CNaviNode        pEnd    = CNaviNode.Create(cx, cy);
                        List <CNaviNode> vecPath = new List <CNaviNode>();
                        if (!m_PathFinding.FindPath(pStart, pEnd, ref vecPath, m_ND))
                        {
                        }
                        else
                        {
                            m_pUnits[i].SetPath(vecPath);
                        }
                    }
                }
            }
        }
Esempio n. 4
0
 public void Copy(CNaviNode pNode)
 {
     x       = pNode.x;
     y       = pNode.y;
     dist    = pNode.dist;
     depth   = pNode.depth;
     pParent = pNode.pParent;
 }
Esempio n. 5
0
 //주어진 노드의 내용을 복사하기
 public void Copy(CNaviNode node)
 {
     x          = node.x;
     y          = node.y;
     dist       = node.dist;
     depth      = node.depth;
     parentNode = node.parentNode;
 }
Esempio n. 6
0
        public static CNaviNode Create(int sx, int sy)
        {
            CNaviNode pNode = new CNaviNode();

            pNode.x = sx;
            pNode.y = sy;
            return(pNode);
        }
Esempio n. 7
0
        public void CalcDist(CNaviNode pDest, int cdepth)
        {
            int deltx = pDest.x - x;
            int delty = pDest.y - y;

            dist  = (deltx * deltx) + (delty * delty);
            depth = cdepth;
        }
Esempio n. 8
0
        public bool IsSamePos(CNaviNode pNode)
        {
            if (x != pNode.x || y != pNode.y)
            {
                return(false);
            }

            return(true);
        }
Esempio n. 9
0
        public CNaviNode Clone()
        {
            CNaviNode pNode = new CNaviNode();

            pNode.x       = x;
            pNode.y       = y;
            pNode.dist    = dist;
            pNode.depth   = depth;
            pNode.pParent = null;
            return(pNode);
        }
Esempio n. 10
0
 //닫힌노드에 해당 노드가 있는지 확인한다
 private bool FindFromCloseNode(CNaviNode pNode)
 {
     for (int i = 0; i < m_vecCloseNode.Count; ++i)
     {
         if (m_vecCloseNode[i].IsSamePos(pNode))
         {
             return(true);
         }
     }
     return(false);
 }
Esempio n. 11
0
        //이노드의 내용을 복사한 새로운 노드를 구성
        public CNaviNode Clone()
        {
            CNaviNode node = new CNaviNode();

            node.x          = x;
            node.y          = y;
            node.dist       = dist;
            node.depth      = depth;
            node.parentNode = null;

            return(node);
        }
Esempio n. 12
0
        //열란노드에 노드 삽입, 중복된 노드가 삽입되지 않도록 처리한다
        private void InsertOpenNode(CNaviNode pNode)
        {
            for (int i = 0; i < mOpenNode.Count; ++i)
            {
                if (mOpenNode[i].IsSamePos(pNode))
                {
                    InsertCloseNode(mOpenNode[i]);
                    mOpenNode[i] = pNode;
                    return;
                }
            }

            mOpenNode.Add(pNode);
        }
Esempio n. 13
0
        public static CNaviNode Create(int sx, int sy, int dx, int dy, int dep)
        {
            CNaviNode pNode = new CNaviNode();

            pNode.x = sx;
            pNode.y = sy;

            int deltx = dx - sx;
            int delty = dy - sy;

            pNode.dist  = (deltx * deltx) + (delty * delty);
            pNode.depth = dep;

            return(pNode);
        }
Esempio n. 14
0
 //노드 p1이 노드 p2보다 저비용이라면(거리가 더가까우며, 탐색깊이가 더 작은지) true
 private bool NodeCompare(CNaviNode p1, CNaviNode p2)
 {
     if (p1.dist < p2.dist)
     {
         return(true);
     }
     if (p1.dist > p2.dist)
     {
         return(false);
     }
     if (p1.depth <= p2.depth)
     {
         return(true);
     }
     return(false);
 }
Esempio n. 15
0
        //해당 지점이 이동가능한 지점인가 확인한다
        virtual public bool IsValidPos(CNaviNode pos)
        {
            if (pos.x < 0 || pos.x >= m_iWidth)
            {
                return(false);
            }
            if (pos.y < 0 || pos.y >= m_iHeight)
            {
                return(false);
            }

            if (m_MapData[(pos.y * m_iWidth) + pos.x] == 0)
            {
                return(false);
            }
            return(true);
        }
Esempio n. 16
0
        //해당 지점이 이동가능한 지점인가 확인한다
        virtual public bool IsValidPos(CNaviNode pos)
        {
            //맵을 벗어난 지점인가?
            if (pos.x < 0 || pos.x >= mWidth)
            {
                return(false);
            }

            //맵을 벗어난 지점인가?
            if (pos.y < 0 || pos.y >= mHeight)
            {
                return(false);
            }

            //이동 불가능한 지점인가?
            if (mMapData[(pos.y * mWidth) + pos.x] == 0)
            {
                return(false);
            }

            return(true);
        }
Esempio n. 17
0
        /*해당 노드에 인접한 이동가능한 이웃노드들을 모두구한다, 리턴값은 이웃의 개수
         * 좌상단, 좌, 좌하단, 상단, 하단, 우상단, 우, 우하단 8방향을 검사해서
         * 이동가능한 지점만 vecList목록에 담는다.
         * */
        virtual public int GetNeighbor(CNaviNode pos, ref List <CNaviNode> vecList)
        {
            int[] distx = new int[3] {
                -1, 0, 1
            };
            int[] disty = new int[3] {
                -1, 0, 1
            };

            for (int y = 0; y < 3; ++y)
            {
                for (int x = 0; x < 3; ++x)
                {
                    int cx = distx[x] + pos.x;
                    int cy = disty[y] + pos.y;

                    //중앙 위치는 필요없다.
                    if (cx == pos.x && cy == pos.y)
                    {
                        continue;
                    }

                    //이동불가능한 지점도 필요없음
                    if (!IsValidPos(cx, cy))
                    {
                        continue;
                    }

                    //이동가능한 지점이면 목록에 추가하기
                    vecList.Add(CNaviNode.Create(cx, cy));
                }
            }

            //구해진 목록의 개수를 리턴
            return(vecList.Count);
        }
Esempio n. 18
0
 //부모노드 설정
 public void SetParent(CNaviNode parent)
 {
     parentNode = parent;
 }
Esempio n. 19
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);
                    }
                }
            }
        }
Esempio n. 20
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);
        }
Esempio n. 21
0
 //닫힌노드에 삽입
 private CNaviNode InsertCloseNode(CNaviNode pNode)
 {
     mCloseNode.Add(pNode);
     return(pNode);
 }
Esempio n. 22
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)
                        {
                            //목표와의 거리가 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);
                    }
                }
            }
        }
Esempio n. 23
0
 public void SetParent(CNaviNode p)
 {
     pParent = p;
 }