Пример #1
0
 public void ResetRuntime(PFAStarPoint parent, PFPoint tiledPoint)
 {
     this.parent     = parent;
     this.tiledPoint = tiledPoint;
     F     = 0;
     G     = 0;
     H     = 0;
     state = PFAStarPointState.Open;
     step  = 0;
 }
Пример #2
0
        public PFAStarPoint CreatAStartPoint(PFAStarPoint parent, PFPoint tiledPoint)
        {
            PFAStarPoint aStartPoint = MctCacheManager.GetInstantiateFromCache <PFAStarPoint>();

            if (aStartPoint == null)
            {
                aStartPoint = new PFAStarPoint(parent, tiledPoint);
            }
            else
            {
                aStartPoint.ResetRuntime(parent, tiledPoint);
            }
            int key = tiledPoint.x * height + tiledPoint.y;

            starPointMap.Add(key, aStartPoint);
            return(aStartPoint);
        }
Пример #3
0
        public void CalculatePath(PFPoint startPoint, PFPoint endPoint, byte limitMask, List <PFAStarPoint> resultList, int maxStep = -1)
        {
            if (maxStep < 0)
            {
                maxStep = width * height;
            }
            ClearOpenAndCloseList();
            starPointMap.Clear();
            PFAStarPoint aStarPoint = CreatAStartPoint(null, startPoint);

            aStarPoint.G = 0;
            aStarPoint.H = (Math.Abs(startPoint.x - endPoint.x) + Math.Abs(startPoint.y - endPoint.y)) * BASE_G_VALUE;
            aStarPoint.F = aStarPoint.G + aStarPoint.H;

            openLinkedList.AddLast(aStarPoint);

            PFAStarResult flag = PFAStarResult.None;
            PFAStarPoint  currentAStarPoint;
            LinkedListNode <PFAStarPoint> tempNode;
            LinkedListNode <PFAStarPoint> tempNodeNext;
            LinkedListNode <PFAStarPoint> tempNodeCurrent;
            PFAStarPoint tempAStarPoint;

            while (true)
            {
                if (openLinkedList.Count == 0)
                {
                    flag = PFAStarResult.Failure;
                    break;
                }

                //获取最小F值的节点
                tempNodeCurrent = openLinkedList.First;
                tempNode        = tempNodeCurrent.Next;
                while (tempNode != null)
                {
                    tempNodeNext = tempNode.Next;
                    if (tempNode.Value.F < tempNodeCurrent.Value.F)
                    {
                        tempNodeCurrent = tempNode;
                    }
                    tempNode = tempNodeNext;
                }
                currentAStarPoint = tempNodeCurrent.Value;

                //把该节点移动到closeList
                openLinkedList.Remove(tempNodeCurrent);
                currentAStarPoint.state = PFAStarPointState.Close;
                closeLinkedList.AddLast(currentAStarPoint);

                //打开该节点的周围节点
                if (currentAStarPoint.step > maxStep)
                {
                    flag = PFAStarResult.OutOfStep;
                    break;
                }
                bool    isFind       = false;
                PFPoint currentPoint = currentAStarPoint.tiledPoint;
                int     cTiledX      = currentAStarPoint.tiledPoint.x;
                int     cTiledY      = currentAStarPoint.tiledPoint.y;
                for (int index = 0; index < AROUND_POINT_POS.Length; index += 2)
                {
                    int dx         = AROUND_POINT_POS[index];
                    int dy         = AROUND_POINT_POS[index + 1];
                    int openTiledX = cTiledX + dx;
                    int openTiledY = cTiledY + dy;
                    if (openTiledX < 0 || openTiledX >= width || openTiledY < 0 || openTiledY >= height)
                    {
                        continue;
                    }

                    //如果阻挡掩码匹配,则视为不可移动
                    int openMask = tiledMasksRuntime[openTiledX, openTiledY];
                    if ((openMask & limitMask) > 0)
                    {
                        continue;
                    }
                    int  gValue          = 0;
                    bool isCanTurnAround = false;
                    if (index == 0 || index == 4 || index == 10 || index == 14)
                    {
                        gValue = SQRT2_G_VALUE;
                        int walkX1 = cTiledX + dx;
                        int walkY1 = cTiledY;
                        if ((walkX1 >= 0) && (walkX1 < width) && (walkY1 >= 0) && (walkY1 < height) && ((tiledMasksRuntime[walkX1, walkY1] & limitMask) == 0))
                        {
                            walkX1 = cTiledX;
                            walkY1 = cTiledY + dy;
                            if ((walkX1 >= 0) && (walkX1 < width) && (walkY1 >= 0) && (walkY1 < height) && ((tiledMasksRuntime[walkX1, walkY1] & limitMask) == 0))
                            {
                                isCanTurnAround = true;
                            }
                        }
                    }
                    else
                    {
                        gValue          = BASE_G_VALUE;
                        isCanTurnAround = true;
                    }
                    if (!isCanTurnAround)
                    {
                        continue;
                    }
                    int key = openTiledX * height + openTiledY;
                    if (starPointMap.TryGetValue(key, out tempAStarPoint))
                    {
                        if (tempAStarPoint.state == PFAStarPointState.Open)
                        {
                            int pointG = currentAStarPoint.G + gValue;
                            if (pointG < tempAStarPoint.G)
                            {
                                tempAStarPoint.G      = pointG;
                                tempAStarPoint.F      = pointG + tempAStarPoint.H;
                                tempAStarPoint.parent = currentAStarPoint;
                            }
                        }
                    }
                    else
                    {
                        PFAStarPoint newAStarPoint = CreatAStartPoint(currentAStarPoint, new PFPoint(openTiledX, openTiledY));
                        newAStarPoint.G    = currentAStarPoint.G + gValue;
                        newAStarPoint.H    = (Math.Abs(openTiledX - endPoint.x) + Math.Abs(openTiledY - endPoint.y)) * BASE_G_VALUE;
                        newAStarPoint.F    = newAStarPoint.G + newAStarPoint.H;
                        newAStarPoint.step = currentAStarPoint.step + 1;
                        openLinkedList.AddLast(newAStarPoint);
                    }
                    if ((openTiledX == endPoint.x) && (openTiledY == endPoint.y))
                    {
                        isFind = true;
                        break;
                    }
                }
                if (isFind)
                {
                    flag = PFAStarResult.Success;
                    break;
                }
            }
            if (flag != PFAStarResult.Success)
            {
                return;
            }
            currentAStarPoint = starPointMap[endPoint.x * height + endPoint.y];
            while (currentAStarPoint != null)
            {
                resultList.Add(currentAStarPoint);
                currentAStarPoint = currentAStarPoint.parent;
            }
        }
Пример #4
0
 public void ReleaseToCache()
 {
     state       = PFAStarPointState.Close;
     this.parent = null;
 }
Пример #5
0
 public PFAStarPoint(PFAStarPoint parent, PFPoint tiledPoint)
 {
     ResetRuntime(parent, tiledPoint);
 }