Ejemplo n.º 1
0
        public long SquareDistance(PFPoint point)
        {
            long dx = x - point.x;
            long dy = y - point.y;

            return(dx * dx + dy * dy);
        }
Ejemplo n.º 2
0
 public PFAStarNode(PFPoint point, byte mask)
 {
     this.point       = point;
     this.mask        = mask;
     parent           = null;
     parentLinkedNode = null;
 }
Ejemplo n.º 3
0
 public void UpdatePosition(PFPoint point)
 {
     nearQuadNodes.Clear();
     parent.FindNearQuadNodes(this, nearQuadNodes);
     if (nearQuadNodes.Count > 0)
     {
         PFPoint movePoint = new PFPoint(0, 0);
         foreach (var quadNode in nearQuadNodes)
         {
             if (quadNode == this)
             {
                 continue;
             }
             long distanceSquare = point.SquareDistance(quadNode.point);
             long dr             = radius + quadNode.radius;
             if (distanceSquare < dr * dr)
             {
                 int     distance      = (int)Math.Sqrt(distanceSquare);
                 PFPoint tempMovePoint = point - quadNode.point;
                 movePoint = movePoint + tempMovePoint.normalized(radius + quadNode.radius - distance);
             }
         }
         point += movePoint;
     }
     this.point = point;
     Update();
 }
Ejemplo n.º 4
0
        /// <summary>
        /// 圆和圆相交
        /// </summary>
        /// <param name="point1">圆心1</param>
        /// <param name="radius1">半径1</param>
        /// <param name="point2">圆心2</param>
        /// <param name="radius2">半径2</param>
        /// <returns></returns>
        public static bool CircleCircleIntersect(PFPoint point1, int radius1, PFPoint point2, int radius2)
        {
            long distanceSquare = point1.SquareDistance(point2);
            long dr             = (long)(radius1 + radius2);

            return(distanceSquare < dr * dr);
        }
Ejemplo n.º 5
0
        public int Distance(PFPoint point)
        {
            long   dx   = x - point.x;
            long   dy   = y - point.y;
            double lenS = (double)(dx * dx + dy * dy);
            int    len  = (int)Math.Sqrt(lenS);

            return(len);
        }
Ejemplo n.º 6
0
 public PFQuadCircle(PFPoint point, int radius)
 {
     shape               = PFQuadShape.Circle;
     nodeState           = PFQuadNodeState.Out;
     this.parent         = null;
     this.parentLinkNode = null;
     this.point          = point;
     this.radius         = radius;
     nearQuadNodes       = new List <PFQuadCircle>();
 }
Ejemplo n.º 7
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;
 }
Ejemplo n.º 8
0
        public void AddMask(PFPoint point, PFAStarMask astarMask)
        {
#if DEBUG
            if (point.x < 0 || point.x >= width || point.y < 0 || point.y >= height)
            {
                Debug.Log(string.Format("ResetMaskRuntime 移除:坐标超出边界"));
                return;
            }
#endif
            tiledMasks[point.x, point.y] |= (byte)astarMask;
        }
Ejemplo n.º 9
0
        public void ResetMaskRuntime(PFPoint point, byte astarMask)
        {
#if DEBUG
            if (point.x < 0 || point.x >= width || point.y < 0 || point.y >= height)
            {
                Debug.Log(string.Format("ResetMaskRuntime 移除:坐标超出边界"));
                return;
            }
#endif
            astarMask |= tiledMasks[point.x, point.y];
            tiledMasksRuntime[point.x, point.y] = astarMask;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// AABB于圆相交
        /// </summary>
        /// <param name="rect">AABB</param>
        /// <param name="point">圆心</param>
        /// <param name="radius">半径</param>
        /// <returns></returns>
        public static bool RectCircleIntersect(PFRect rect, PFPoint point, int radius)
        {
            long cx = (rect.x + rect.x1) / 2;
            long cy = (rect.y + rect.y1) / 2;

            long vx = Math.Abs(point.x - cx);
            long vy = Math.Abs(point.y - cy);

            long hx = rect.x1 - cx;
            long hy = rect.y1 - cy;

            long ux = Math.Max(vx - hx, 0);
            long uy = Math.Max(vy - hy, 0);

            return(ux * ux + uy * uy <= (long)radius * (long)radius);
        }
Ejemplo n.º 11
0
        public void UpdatePosition(PFPoint point)
        {
            int lastTiledX = this.point.x / parent.tiledWidth;
            int lastTiledY = this.point.y / parent.tiledHeight;
            int tiledX     = point.x / parent.tiledWidth;
            int tiledY     = point.y / parent.tiledHeight;

            if ((lastTiledX == tiledX) && (lastTiledY == tiledY))
            {
                this.point = point;
                return;
            }
            parent.RemoveAStarNode(this);
            this.point = point;
            parent.AddAStarNode(this);
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
0
        public static PFPoint MoveTo(PFPoint startPoint, PFPoint endPoint, int stepLen)
        {
            long dx  = endPoint.x - startPoint.x;
            long dy  = endPoint.y - startPoint.y;
            long len = endPoint.Distance(startPoint);

            if (stepLen > len)
            {
                return(endPoint);
            }
            else
            {
                long moveDistanceX = (int)(stepLen * dx / len);
                long moveDistanceY = (int)(stepLen * dy / len);
                long nextX         = startPoint.x + moveDistanceX;
                long nextY         = startPoint.y + moveDistanceY;
                return(new PFPoint((int)nextX, (int)nextY));
            }
        }
Ejemplo n.º 14
0
 public void     InitRuntime(PFPoint point, int radius)
 {
     this.point  = point;
     this.radius = radius;
 }
Ejemplo n.º 15
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;
            }
        }
Ejemplo n.º 16
0
 public void InitRuntime(PFPoint point, byte mask)
 {
     this.point = point;
     this.mask  = mask;
 }
Ejemplo n.º 17
0
 public PFAStarPoint(PFAStarPoint parent, PFPoint tiledPoint)
 {
     ResetRuntime(parent, tiledPoint);
 }