protected override bool CanPass(int xWithoutOffset, int yWithoutOffset) { if (!AStarUtil.CanPass(astarMapPath.GetFinalGrids(), xWithoutOffset, yWithoutOffset, canPassObstacleTypes, canPassTerrainTypes)) { return(false); } return(true); }
//检测两点间直线是否可通过 public static bool CanLinePass(AStarMapPath astarMapPath, Vector2Int pointA, Vector2Int pointB, int[] canPassObstacleTypes, int[] canPassTerrainTypes, bool canOut = false) { if (!canOut && (!IsInRange(astarMapPath.GetFinalGrids(), pointA) || !IsInRange(astarMapPath.GetFinalGrids(), pointB))) { return(false); } var linePointList = GetLinePointList(pointA, pointB); return(CanPass(astarMapPath, linePointList, canPassObstacleTypes, canPassTerrainTypes, canOut)); }
//获取range范围内的可以通过的格子列表 public static List <Vector2Int> GetRangeFreePointList(AStarMapPath astarMapPath, int x1, int y1, int x2, int y2, List <Vector2Int> exceptPointList, int[] canPassObstacleTypes, int[] canPassTerrainTypes) { List <Vector2Int> list = new List <Vector2Int>(); for (int x = x1; x <= x2; x++) { for (int y = y1; y <= y2; y++) { if (!IsInRange(astarMapPath.GetFinalGrids(), x, y)) { continue; } bool canPass = CanPass(astarMapPath, x, y, canPassObstacleTypes, canPassTerrainTypes); if (canPass) { Vector2Int p = new Vector2Int(x, y); if (exceptPointList == null || !exceptPointList.Contains(p)) { list.Add(p); } } } } return(list); }
//获取P点四周为的可以通过的点 public static Vector2Int?FindAroundFreePoint(AStarMapPath astarMapPath, Vector2Int basePoint, List <Vector2Int> exceptPointList, int[] canPassObstacleTypes, int[] canPassTerrainTypes, RandomManager randomManager = null) { randomManager = randomManager ?? Client.instance.randomManager; if (!IsInRange(astarMapPath.GetFinalGrids(), basePoint)) { return(null); } if (CanPass(astarMapPath, basePoint.x, basePoint.y, canPassObstacleTypes, canPassTerrainTypes) && (exceptPointList == null || !exceptPointList.Contains(basePoint))) { return(basePoint); } int max = Math.Max(Math.Max(basePoint.x, astarMapPath.Width() - basePoint.x), Math.Max(basePoint.y, astarMapPath.Height() - basePoint.y)); for (int i = 1; i <= max; i++) { List <Vector2Int> list = GetAroundFreePointList(astarMapPath, basePoint, i, canPassObstacleTypes, canPassTerrainTypes); if (exceptPointList != null) { list.RemoveElementsOfSub(exceptPointList); } if (list.Count > 0) { return(list[randomManager.RandomInt(0, list.Count)]); } } return(null); }
//检测某个点是否可通过 // can_out 是否允许在场景外 public static bool CanPass(AStarMapPath astarMapPath, int x, int y, int[] canPassObstacleTypes, int[] canPassTerrainTypes, bool canOut = false) { if (!IsInRange(astarMapPath.GetFinalGrids(), x, y)) { return(canOut); } int grid_type = astarMapPath.GetFinalGrids()[x][y]; // 固有地形+障碍 if (!IsValidObstacleType(grid_type)) // 填充区域 { return(canOut); } if (!CanPass(astarMapPath.GetFinalGrids(), x, y, canPassObstacleTypes, canPassTerrainTypes)) { return(false); } return(true); }
//获得两点间可通过的最远点 // can_out 是否允许通过场景外 public static Vector2Int GetMostLinePassPoint(AStarMapPath astarMapPath, Vector2Int lp, Vector2Int tp, int[] canPassObstacleTypes, int[] canPassTerrainTypes, bool canOut = false) { if (!canOut && !IsInRange(astarMapPath.GetFinalGrids(), lp)) { return(lp); } List <Vector2Int> pointList = GetLinePointList(lp, tp); return(GetMostPassPoint(astarMapPath, pointList, canPassObstacleTypes, canPassTerrainTypes, canOut)); }
//直角寻路(先横向再纵向寻路) public static List <Vector2Int> BorderFindPath(AStarMapPath astarMapPath, Vector2Int pointA, Vector2Int pointB, int[] canPassObstacleTypes, int[] canPassTerrainTypes) { if (!AStarUtil.IsInRange(astarMapPath.GetFinalGrids(), pointA) || !AStarUtil.IsInRange(astarMapPath.GetFinalGrids(), pointB)) { return(null); } List <Vector2Int> list = new List <Vector2Int> { pointA }; int dv = pointB.x > pointA.x ? 1 : -1; for (int x = pointA.x + dv; x *dv <= pointB.x *dv; x += dv) { // LogCat.log(x, point_a.y); if (!AStarUtil.CanPass(astarMapPath, x, pointA.y, canPassObstacleTypes, canPassTerrainTypes)) { return(null); } list.Add(new Vector2Int(x, pointA.y)); } dv = pointB.y > pointA.y ? 1 : -1; for (int y = pointA.y + dv; y *dv < pointB.y *dv; y += dv) { if (!AStarUtil.CanPass(astarMapPath, pointB.x, y, canPassObstacleTypes, canPassTerrainTypes)) { return(null); } list.Add(new Vector2Int(pointB.x, y)); } list.Add(pointB); return(list); }
//获取P点四周为+-out_count的可以通过的点 public static Vector2Int?FindAroundFreePoint(AStarMapPath astarMapPath, Vector2Int basePoint, int outCount, int[] canPassObstacleTypes, int[] canPassTerrainTypes, RandomManager randomManager = null) { randomManager = randomManager ?? Client.instance.randomManager; if (!IsInRange(astarMapPath.GetFinalGrids(), basePoint)) { return(null); } List <Vector2Int> list = GetAroundFreePointList(astarMapPath, basePoint, outCount, canPassObstacleTypes, canPassTerrainTypes); if (list.Count > 0) { return(list[randomManager.RandomInt(0, list.Count)]); } return(null); }
//对角线寻路 public static List <Vector2Int> DiagonallyFindPath(AStarMapPath astarMapPath, Vector2Int pointA, Vector2Int pointB, int[] canPassObstacleTypes, int[] canPassTerrainTypes) { if (!AStarUtil.IsInRange(astarMapPath.GetFinalGrids(), pointA) || !AStarUtil.IsInRange(astarMapPath.GetFinalGrids(), pointB)) { return(null); } List <Vector2Int> list = new List <Vector2Int>(); int dx = pointB.x - pointA.x; int dy = pointB.y - pointA.y; if (Math.Abs(dx) > Math.Abs(dy)) { int x1; if (dx > 0) { x1 = pointA.x + Math.Abs(dy); } else { x1 = pointA.x - Math.Abs(dy); } Vector2Int p = new Vector2Int(x1, pointB.y); if (!AStarUtil.CanPass(astarMapPath, p.x, p.y, canPassObstacleTypes, canPassTerrainTypes)) { return(null); } List <Vector2Int> list1 = AStarUtil.GetLinePointList(pointA, p); if (!AStarUtil.CanPass(astarMapPath, list1, canPassObstacleTypes, canPassTerrainTypes)) { return(null); } List <Vector2Int> list2 = AStarUtil.GetLinePointList(p, pointB); if (!AStarUtil.CanPass(astarMapPath, list2, canPassObstacleTypes, canPassTerrainTypes)) { return(null); } list.AddRange(list1); list.RemoveLast(); //删掉p list.AddRange(list2); } else { int y1; if (dy > 0) { y1 = pointA.y + Math.Abs(dx); } else { y1 = pointA.y - Math.Abs(dx); } Vector2Int p = new Vector2Int(pointB.x, y1); if (!AStarUtil.CanPass(astarMapPath, p.x, p.y, canPassObstacleTypes, canPassTerrainTypes)) { return(null); } List <Vector2Int> list1 = AStarUtil.GetLinePointList(pointA, p); if (!AStarUtil.CanPass(astarMapPath, list1, canPassObstacleTypes, canPassTerrainTypes)) { return(null); } List <Vector2Int> list2 = AStarUtil.GetLinePointList(p, pointB); if (!AStarUtil.CanPass(astarMapPath, list2, canPassObstacleTypes, canPassTerrainTypes)) { return(null); } list.AddRange(list1); list.RemoveLast(); //删掉p list.AddRange(list2); } return(list); }
//先对角线查找,再直角查找 public static List <Vector2Int> DirectFindPath(AStarMapPath astarMapPath, Vector2Int pointA, Vector2Int pointB, int[] canPassObstacleTypes, int[] canPassTerrainTypes) { if (!AStarUtil.IsInRange(astarMapPath.GetFinalGrids(), pointA) || !AStarUtil.IsInRange(astarMapPath.GetFinalGrids(), pointB)) { return(null); } List <Vector2Int> list = null; if (pointA.Equals(pointB)) // 同一点 { list = new List <Vector2Int> { pointA }; } else if (pointA.x == pointB.x) { list = new List <Vector2Int> { pointA }; int dv = pointB.y > pointA.y ? 1 : -1; for (int y = pointA.y + dv; y *dv < pointB.y *dv; y += dv) { if (!AStarUtil.CanPass(astarMapPath, pointA.x, y, canPassObstacleTypes, canPassTerrainTypes)) { return(null); } list.Add(new Vector2Int(pointA.x, y)); } list.Add(pointB); } else if (pointA.y == pointB.y) { list = new List <Vector2Int> { pointA }; int dv = pointB.x > pointA.x ? 1 : -1; for (int x = pointA.x + dv; x *dv < pointB.x *dv; x += dv) { if (!AStarUtil.CanPass(astarMapPath, x, pointA.y, canPassObstacleTypes, canPassTerrainTypes)) { return(null); } list.Add(new Vector2Int(x, pointA.y)); } list.Add(pointB); } else { //先对角线查找,再直角查找 list = DiagonallyFindPath(astarMapPath, pointA, pointB, canPassObstacleTypes, canPassTerrainTypes); if (list == null) { list = DiagonallyFindPath(astarMapPath, pointB, pointA, canPassObstacleTypes, canPassTerrainTypes); if (list == null) { list = BorderFindPath(astarMapPath, pointA, pointB, canPassObstacleTypes, canPassTerrainTypes); if (list == null) { list = BorderFindPath(astarMapPath, pointB, pointA, canPassObstacleTypes, canPassTerrainTypes); list?.Reverse(); } } else { list.Reverse(); } } } return(list); }
private static Vector2Int GetNearestNearbyPoint(AStarMapPath astarMapPath, Vector2Int pointA, Vector2Int pointB, int[] canPassObstacleTypes, int[] canPassTerrainTypes) { int dx = pointB.x > pointA.x ? 1 : pointB.x < pointA.x ? -1 : 0; int dy = pointB.y > pointA.y ? 1 : pointB.y < pointA.y ? -1 : 0; int minDistance = GetMapDistance(pointA, pointB); Vector2Int minPoint = pointA; int x, y; x = pointA.x + dx; y = pointA.y; bool s1 = false; if (IsInRange(astarMapPath.GetFinalGrids(), x, y)) { Vector2Int p = new Vector2Int(x, y); if (CanPass(astarMapPath, x, y, canPassObstacleTypes, canPassTerrainTypes)) { s1 = true; int d = GetMapDistance(p, pointB); if (d < minDistance) { minPoint = p; minDistance = d; } } } x = pointA.x; y = pointA.y + dy; bool s2 = false; if (IsInRange(astarMapPath.GetFinalGrids(), x, y)) { Vector2Int p = new Vector2Int(x, y); if (CanPass(astarMapPath, x, y, canPassObstacleTypes, canPassTerrainTypes)) { s2 = true; int d = GetMapDistance(p, pointB); if (d < minDistance) { minPoint = p; minDistance = d; } } } if (s1 || s2) { x = pointA.x + dx; y = pointA.y + dy; if (IsInRange(astarMapPath.GetFinalGrids(), x, y)) { Vector2Int p = new Vector2Int(x, y); if (CanPass(astarMapPath, x, y, canPassObstacleTypes, canPassTerrainTypes)) { int d = GetMapDistance(p, pointB); if (d < minDistance) { minPoint = p; minDistance = d; } } } } return(minPoint); }
//获取P点四周为+-out_count的可以通过的点列表 public static List <Vector2Int> GetAroundFreePointList(AStarMapPath astarMapPath, Vector2Int basePoint, int outCount, int[] canPassObstacleTypes, int[] canPassTerrainTypes) { List <Vector2Int> list = new List <Vector2Int>(); int x, y; int field = GetField(astarMapPath.GetFinalGrids()[basePoint.x][basePoint.y]); // 所属区块值 bool canPass = CanPass(astarMapPath, basePoint.x, basePoint.y, canPassObstacleTypes, canPassTerrainTypes); // 是否起始在障碍点 y = basePoint.y - outCount; // 下边一行 if (IsInRangeY(astarMapPath.GetFinalGrids(), y)) { for (x = basePoint.x - outCount; x <= basePoint.x + outCount; x++) { if (IsInRange(astarMapPath.GetFinalGrids(), x, y) && (!canPass || field == GetField(astarMapPath.GetFinalGrids()[x][y])) && CanPass(astarMapPath, x, y, canPassObstacleTypes, canPassTerrainTypes)) { list.Add(new Vector2Int(x, y)); } } } x = basePoint.x + outCount; // 右边一行 if (IsInRangeX(astarMapPath.GetFinalGrids(), x)) { for (y = basePoint.y - outCount; y <= basePoint.y + outCount; y++) { if (IsInRange(astarMapPath.GetFinalGrids(), x, y) && (!canPass || field == GetField(astarMapPath.GetFinalGrids()[x][y])) && CanPass(astarMapPath, x, y, canPassObstacleTypes, canPassTerrainTypes)) { list.Add(new Vector2Int(x, y)); } } } y = basePoint.y + outCount; // 上边一行 if (IsInRangeY(astarMapPath.GetFinalGrids(), y)) { for (x = basePoint.x + outCount; x >= basePoint.x - outCount; x--) { if (IsInRange(astarMapPath.GetFinalGrids(), x, y) && (!canPass || field == GetField(astarMapPath.GetFinalGrids()[x][y])) && CanPass(astarMapPath, x, y, canPassObstacleTypes, canPassTerrainTypes)) { list.Add(new Vector2Int(x, y)); } } } x = basePoint.x - outCount; // 左边一行 if (IsInRangeX(astarMapPath.GetFinalGrids(), x)) { for (y = basePoint.y + outCount; y >= basePoint.y - outCount; y--) { if (IsInRange(astarMapPath.GetFinalGrids(), x, y) && (!canPass || field == GetField(astarMapPath.GetFinalGrids()[x][y])) && CanPass(astarMapPath, x, y, canPassObstacleTypes, canPassTerrainTypes)) { list.Add(new Vector2Int(x, y)); } } } return(list); }