public long SquareDistance(PFPoint point) { long dx = x - point.x; long dy = y - point.y; return(dx * dx + dy * dy); }
public PFAStarNode(PFPoint point, byte mask) { this.point = point; this.mask = mask; parent = null; parentLinkedNode = null; }
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(); }
/// <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); }
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); }
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>(); }
public void ResetRuntime(PFAStarPoint parent, PFPoint tiledPoint) { this.parent = parent; this.tiledPoint = tiledPoint; F = 0; G = 0; H = 0; state = PFAStarPointState.Open; step = 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; }
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; }
/// <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); }
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); }
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); }
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)); } }
public void InitRuntime(PFPoint point, int radius) { this.point = point; this.radius = radius; }
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; } }
public void InitRuntime(PFPoint point, byte mask) { this.point = point; this.mask = mask; }
public PFAStarPoint(PFAStarPoint parent, PFPoint tiledPoint) { ResetRuntime(parent, tiledPoint); }