public Stack <ASPoint> FindPath(ASPoint start, ASPoint end) { OpenList.Clear(); CloseList.Clear(); PointPool.Clear(); AddPointInPool(start); AddPointInPool(end); OpenList.Add(start); while (OpenList.Count > 0) { // 找到F最小的点 var point = GetMinFOpenPoint(); OpenList.Remove(point); CloseList.Add(point); // var surroundPoints = GetSurroundPoints(point); foreach (var p in surroundPoints) { if (OpenList.Contains(p)) { int newG = point.G + 10; if (newG < p.G) { p.ParentPoint = point; p.G = newG; p.CalF(); } } else if (!CloseList.Contains(p)) { p.ParentPoint = point; p.G = 10; p.H = (Math.Abs(end.X - p.X) + Math.Abs(end.Y - p.Y)) * 10; p.CalF(); OpenList.Add(p); } } if (OpenList.Contains(end)) { Stack <ASPoint> path = new Stack <ASPoint>(); ASPoint curPoint = end; do { path.Push(curPoint); curPoint = curPoint.ParentPoint; } while (curPoint != null); return(path); } } return(null); }
public void AddPointInPool(ASPoint point) { Dictionary <int, ASPoint> dict; if (!PointPool.TryGetValue(point.X, out dict)) { dict = new Dictionary <int, ASPoint>(); PointPool.Add(point.X, dict); dict.Add(point.Y, point); } else if (!dict.ContainsKey(point.Y)) { dict.Add(point.Y, point); } }
protected int GetDirection(ASPoint startPoint, ASPoint endPoint) { if (startPoint.X > endPoint.X) { return(1); } else if (startPoint.Y > endPoint.Y) { return(2); } else if (startPoint.X < endPoint.X) { return(3); } else if (startPoint.Y < endPoint.Y) { return(4); } return(0); }
/// <summary> /// 获取可行走的相邻点 /// </summary> /// <returns>The surround points.</returns> /// <param name="point">Point.</param> public List <ASPoint> GetSurroundPoints(ASPoint point) { var list = new List <ASPoint>(); ASPoint[] points = { GetPointFromPool(point.X + 1, point.Y), GetPointFromPool(point.X - 1, point.Y), GetPointFromPool(point.X, point.Y + 1), GetPointFromPool(point.X, point.Y - 1) }; for (int i = 0; i < points.Length; i++) { var p = points[i]; if (Map.IsMoveable(p)) { list.Add(p); } } return(list); }
public ASPoint GetPointFromPool(int x, int y) { Dictionary <int, ASPoint> dict; if (PointPool.TryGetValue(x, out dict)) { ASPoint point; if (!dict.TryGetValue(y, out point)) { point = new ASPoint(x, y); dict.Add(y, point); } return(point); } else { var point = new ASPoint(x, y); dict = new Dictionary <int, ASPoint>(); PointPool.Add(x, dict); dict.Add(y, point); return(point); } }
/// <summary> /// 判断是否可行 /// </summary> /// <returns><c>true</c>, if moveable was ised, <c>false</c> otherwise.</returns> /// <param name="point">Point.</param> public bool IsMoveable(ASPoint point) { if (!IsInMap(point.X, point.Y)) { return(false); } var cid = MapHelper.GetCid(point); GameObject tileGo; if (!m_TileGoMap.TryGetValue(cid, out tileGo)) { return(false); } if (!tileGo.activeSelf) { return(false); } var tileController = tileGo.GetComponent <TileController>(); return(tileController.MapObjectType <= (int)MapHelper.EMapObject.Obstacle); }
public List<ASCase> getAdjCase(ASCase current,bool bdiagonales = false) { List<ASCase> list = new List<ASCase>(); ASPoint Point = new ASPoint(); // Haut Point.X = current.Point.X; Point.Y = current.Point.Y + 1; if (inMap(Point) && NearMovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 1; list.Add(Case); } // Droite Point.X = current.Point.X +1; Point.Y = current.Point.Y; if (inMap(Point) && NearMovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 1; list.Add(Case); } // Gauche Point.X = current.Point.X -1 ; Point.Y = current.Point.Y; if (inMap(Point) && NearMovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 1; list.Add(Case); } // Bas Point.X = current.Point.X ; Point.Y = current.Point.Y -1; if (inMap(Point) && NearMovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 1; list.Add(Case); } if (bdiagonales) { // Haut gauche Point.X = current.Point.X - 1 ; Point.Y = current.Point.Y + 1; if (inMap(Point) && MovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G +2; list.Add(Case); } // Haut Droite Point.X = current.Point.X + 1; Point.Y = current.Point.Y + 1; if (inMap(Point) && MovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 2; list.Add(Case); } // Bas Gauche Point.X = current.Point.X - 1; Point.Y = current.Point.Y - 1; if (inMap(Point) && MovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 2; list.Add(Case); } // Bas Droite Point.X = current.Point.X + 1 ; Point.Y = current.Point.Y - 1; if (inMap(Point) && MovementFree(Point)) { ASCase Case = new ASCase(Point.Clone(), current); Case.CalculH(_end); Case.G = current.G + 2; list.Add(Case); } } return list; }
public bool NearMovementFree(ASPoint point) { return MovementFree(point) && NearFree(point); }
public bool NearFree(ASPoint point) { return !_obstacles.Exists(ASCase.Proche(point, 1)); }
public bool MovementFree(ASPoint point) { return !_obstacles.Exists(ASCase.byPos(point)); }
public bool inMap(ASPoint point) { return (point.X >= 0)&& (point.Y >= 0)&& (point.X < _lignes)&& (point.Y < _colonnes); }
public ASCase getCase(ASPoint p) { return _map[p.X,p.Y]; }
public static int GetCid(ASPoint point) { return(GetCid(point.X, point.Y)); }
protected void MoveLine() { ASPoint startPoint = new ASPoint((int)CurTilePoint.x, (int)CurTilePoint.y); var adventureController = gameObject.GetComponent <AdventureController>(); // 计算同一方向的最远格子 var asPoint = m_MovingPath.Peek(); List <ASPoint> linePoints = new List <ASPoint>(); var curDirection = GetDirection(startPoint, asPoint); var curPoint = startPoint; while (m_MovingPath.Count > 1) { var nextPoint = m_MovingPath.Peek(); var direction = GetDirection(curPoint, nextPoint); if (direction == curDirection) { linePoints.Add(nextPoint); m_MovingPath.Pop(); } else { break; } curPoint = nextPoint; } // 最后一格是否遇到事件 bool meetEvent = false; if (m_MovingPath.Count == 1) { var nextPoint = m_MovingPath.Peek(); if (adventureController.HasEvent(new Vector2(nextPoint.X, nextPoint.Y))) { meetEvent = true; } else { var direction = GetDirection(curPoint, nextPoint); if (direction == curDirection) { linePoints.Add(nextPoint); m_MovingPath.Pop(); } } } // 人物转向 if (asPoint.X - startPoint.X > 0 || asPoint.Y - startPoint.Y > 0) { ChangeAnimation("front", "walk"); m_ArmatureComp.armature.flipX = asPoint.X - startPoint.X > 0; } else { ChangeAnimation("back", "walk"); m_ArmatureComp.armature.flipX = asPoint.Y - startPoint.Y < 0; } // 人物连贯动作 if (linePoints.Count > 0) { GoPlayer.transform.DOLocalMove(MapHelper.TileToMapPoint(new Vector2(linePoints.Last().X, linePoints.Last().Y)), linePoints.Count * 0.4f); } // 人物移动中逻辑拆分 var sequence = DOTween.Sequence(); foreach (var nextPoint in linePoints) { sequence.AppendCallback((() => { var sortingOrder = MapHelper.GetTileUnitSortOrder(new Vector2(nextPoint.X, nextPoint.Y), MapHelper.ETileObject.Hero); if (sortingOrder > m_ArmatureComp.sortingOrder) { SortingOrder = sortingOrder; } })) .AppendInterval(0.2f) .AppendCallback((() => { OnFinishMoveToTile(new Vector2(nextPoint.X, nextPoint.Y), null, true); })) .AppendInterval(0.2f) .AppendCallback((() => { CurTilePoint = new Vector2(nextPoint.X, nextPoint.Y); SortingOrder = MapHelper.GetTileUnitSortOrder(CurTilePoint, MapHelper.ETileObject.Hero); })); } sequence.AppendCallback((() => { if (meetEvent) { var nextPoint = m_MovingPath.Pop(); adventureController.TriggerEvent(new Vector2(nextPoint.X, nextPoint.Y)); ChangeAnimation(m_ArmatureComp.armature.name, "idel"); m_MoveSequence = null; } else if (m_MovingPath.Count > 0) { MoveLine(); } else { ChangeAnimation(m_ArmatureComp.armature.name, "idel"); m_MoveSequence = null; } })); m_MoveSequence = sequence; }