| | |
| | | public HouseInfo(HousePathInfo houseInfo) |
| | | { |
| | | this.HousePathInfo = houseInfo; |
| | | InitPathInfo(); |
| | | InitPathInfo(null); |
| | | } |
| | | |
| | | public HouseInfo(Int32 index,MapType mapType,bool isEnd, HIDCode[] skills) |
| | | public HouseInfo(Int32 index,MapType mapType,bool isEnd, HIDCode[] skills,Int32[] withoutNumber) |
| | | { |
| | | this.Index = index; |
| | | this.MapType = mapType; |
| | |
| | | throw e; |
| | | } |
| | | |
| | | InitPathInfo(); |
| | | InitPathInfo(withoutNumber); |
| | | } |
| | | |
| | | |
| | |
| | | /// </summary> |
| | | public Int32 Index { get; set; } |
| | | |
| | | ///// <summary> |
| | | ///// 下一房间编号 |
| | | ///// </summary> |
| | | //public Int32 NextIndex { get; set; } |
| | | |
| | | ///// <summary> |
| | | ///// 判断下一房间是否打开索引 |
| | | ///// </summary> |
| | | //public Int32 OpenStatusDetectIndex { get; set; } |
| | | |
| | | private Direction[] doorDirection = null; |
| | | /// <summary> |
| | | /// 门的位置 |
| | | /// todo:cacel |
| | | /// </summary> |
| | | public Direction[] DoorDirection { get; set; } |
| | | public Direction[] DoorDirection |
| | | { |
| | | get |
| | | { |
| | | return doorDirection; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 技能队列 |
| | | /// </summary> |
| | | public SkillQueue Skills { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 房间的Y轴中间线,为负值,代表从游戏框向上移的像素值 |
| | | /// </summary> |
| | | public Int32 HouseCenterMoveLine { get; set; } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 是否为结束房间 |
| | |
| | | /// 定位字典 |
| | | /// </summary> |
| | | private Dictionary<Int32, ZTPoint> LocationDic = new Dictionary<int, ZTPoint>(); |
| | | |
| | | /// <summary> |
| | | /// 排除数字 |
| | | /// </summary> |
| | | public Dictionary<Int32, bool> WithoutNumber = new Dictionary<int, bool>(); |
| | | |
| | | /// <summary> |
| | | /// 屏幕坐标转地图坐标 |
| | |
| | | /// </summary> |
| | | /// <param name="start"></param> |
| | | /// <param name="end"></param> |
| | | public List<ZTPoint> FindPath(ref ZTPoint start, ref ZTPoint end) |
| | | public List<ZTPoint> FindPath(ZTPoint start, ZTPoint end) |
| | | { |
| | | |
| | | if (start.Equals(end)) |
| | | { |
| | | return new List<ZTPoint>(); |
| | |
| | | } |
| | | |
| | | //确保两点不在障碍物里 |
| | | bool inObstacle = EnsureNotInObstacle(ref start); |
| | | inObstacle = EnsureNotInObstacle(ref end) || inObstacle; |
| | | ZTPoint startPathGuid = ZTPoint.Empty; |
| | | ZTPoint endPathGuid = ZTPoint.Empty; |
| | | bool inObstacle = EnsureNotInObstacle(out startPathGuid, start); |
| | | inObstacle = EnsureNotInObstacle(out endPathGuid, end) || inObstacle; |
| | | |
| | | //查询两点间是否连通 |
| | | if (inObstacle && Iscross(start, end)) |
| | | if (inObstacle && Iscross(startPathGuid, endPathGuid)) |
| | | { |
| | | //两点直接连通 |
| | | return new List<ZTPoint>() { end }; |
| | | List<ZTPoint> points = new List<ZTPoint>(); |
| | | if (!start.Equals(startPathGuid)) |
| | | { |
| | | points.Add(startPathGuid); |
| | | } |
| | | if (!end.Equals(endPathGuid)) |
| | | { |
| | | points.Add(endPathGuid); |
| | | } |
| | | points.Add(end); |
| | | return points; |
| | | } |
| | | |
| | | |
| | | //把两点添加到寻路网中 |
| | | AddConnectivityEdgeToFinder(start, end); |
| | | AddConnectivityEdgeToFinder(startPathGuid, endPathGuid); |
| | | |
| | | //寻路,组合路径 |
| | | List<ZTPoint> paths = this.PathFinder.ShortestPath(start, end); |
| | | List<ZTPoint> paths = this.PathFinder.ShortestPath(startPathGuid, endPathGuid); |
| | | |
| | | //去除寻路网中 |
| | | RemoveStartAndEndVerticeFromFinder(start, end); |
| | | RemoveStartAndEndVerticeFromFinder(endPathGuid, endPathGuid); |
| | | |
| | | //生成的路径不包含第一个点,拟如果第一个点是路径引导,则加入路径 |
| | | if (!start.Equals(startPathGuid)) |
| | | { |
| | | paths.Insert(0, startPathGuid); |
| | | } |
| | | |
| | | //如果最后一个点是路径引导点,测加上终点 |
| | | if (!end.Equals(endPathGuid)) |
| | | { |
| | | paths.Add(end); |
| | | } |
| | | |
| | | return paths; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 查找到下一关进门点 |
| | | /// 是否在下一关进门点区域内 |
| | | /// </summary> |
| | | /// <param name="nextGatePoint"></param> |
| | | /// <param name="rolePosition"></param> |
| | | /// <returns></returns> |
| | | public List<ZTPoint> FindDoorPath(out Int32 doorIndex,ZTPoint rolePosition) |
| | | public bool IsInNextGatePoint(out ParametersPoint nextGatePoint, ZTPoint rolePosition) |
| | | { |
| | | doorIndex = 0; |
| | | ZTPoint end = this.HousePathInfo.NextGates[0].Point; |
| | | return FindPath(ref rolePosition, ref end); |
| | | nextGatePoint = ParametersPoint.Empty; |
| | | const Int32 X_OFFSET = 5; |
| | | const Int32 Y_OFFSET = 5; |
| | | for (Int32 i = 0; i < this.HousePathInfo.NextGates.Count; i++) |
| | | { |
| | | ParametersPoint nextGate = this.HousePathInfo.NextGates[i]; |
| | | if (GeoHelper.IsInRect(rolePosition, new ZTRectangle(nextGate.Point.X- X_OFFSET, nextGate.Point.Y- Y_OFFSET, nextGate.Point.X+ X_OFFSET, nextGate.Point.Y+ Y_OFFSET))) |
| | | { |
| | | nextGatePoint = nextGate; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取指定方向的进门点 |
| | | /// </summary> |
| | | /// <param name="dir"></param> |
| | | /// <returns></returns> |
| | | public ZTPoint GetNextGatePoint(Direction dir) |
| | | { |
| | | int dirNumber = 0; |
| | | switch (dir) |
| | | { |
| | | case Direction.Up: |
| | | dirNumber = 0; |
| | | break; |
| | | case Direction.Right: |
| | | dirNumber = 1; |
| | | break; |
| | | case Direction.Bottom: |
| | | dirNumber = 2; |
| | | break; |
| | | case Direction.Left: |
| | | dirNumber = 3; |
| | | break; |
| | | } |
| | | for (int i = 0; i < this.HousePathInfo.NextGates.Count; i++) |
| | | { |
| | | if (dirNumber == this.HousePathInfo.NextGates[i].Parameter) |
| | | { |
| | | return this.HousePathInfo.NextGates[i].Point; |
| | | } |
| | | } |
| | | throw new ArgumentOutOfRangeException("house index:" + this.Index.ToString() + ",direction :" + dir.ToString() + " is not exists!~"); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// <returns></returns> |
| | | private bool Iscross(ZTPoint start, ZTPoint end) |
| | | { |
| | | |
| | | for (int i = 0; i < this.HousePathInfo.Obstacles.Count; i++) |
| | | { |
| | | Intersection interSection = GeometryHelper.IntersectionOf(new ZTLinePoint(start, end), this.HousePathInfo.Obstacles[i]); |
| | | Intersection interSection = GeoHelper.IntersectionOf(new ZTLinePoint(start, end), this.HousePathInfo.Obstacles[i]); |
| | | if (interSection != Intersection.None) |
| | | { |
| | | return false; |
| | |
| | | /// <summary> |
| | | /// 是否在障碍物里,如果在障碍物里则返回最近的不在障碍物点 |
| | | /// </summary> |
| | | /// <param name="point"></param> |
| | | /// <param name="pathGuidePoint"></param> |
| | | /// <returns>true:在障碍物,false:不在障碍物里</returns> |
| | | private bool EnsureNotInObstacle(ref ZTPoint point) |
| | | private bool EnsureNotInObstacle(out ZTPoint pathGuidePoint,ZTPoint source) |
| | | { |
| | | ZTPoint source = new ZTPoint(point.X, point.Y); |
| | | pathGuidePoint = ZTPoint.Empty; |
| | | |
| | | //点是否在障碍物里 |
| | | ZTPolygon obstacle = ZTPolygon.Empty; |
| | | for (int i = 0; i < this.HousePathInfo.Obstacles.Count; i++) |
| | | { |
| | | ZTPolygon temp = this.HousePathInfo.Obstacles[i]; |
| | | if (GeometryHelper.IntersectionOf(point, temp) != Intersection.None) |
| | | if (GeoHelper.IntersectionOf(source, temp) != Intersection.None) |
| | | { |
| | | obstacle = this.HousePathInfo.Obstacles[i]; |
| | | break; |
| | |
| | | if (obstacle.Equals(ZTPolygon.Empty)) |
| | | { |
| | | //不在障碍物内 |
| | | pathGuidePoint = source; |
| | | return false; |
| | | } |
| | | |
| | | //点是否在路径导引区域 |
| | | for (int i = 0; i < this.HousePathInfo.PathGuides.Count; i++) |
| | | { |
| | | ZTTargetPolygon temp = this.HousePathInfo.PathGuides[i]; |
| | | if (GeoHelper.IntersectionOf(source, temp.Polygon) != Intersection.None) |
| | | { |
| | | pathGuidePoint = temp.Target; |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | |
| | | //计算距离障碍物外最近的距离 |
| | | double distance = 0; |
| | |
| | | if (i == 0) |
| | | { |
| | | lastPoint = obstacle.Points[i]; |
| | | distance = GeometryHelper.GetPointDistance(lastPoint, point); |
| | | distance = GeoHelper.GetPointDistance(lastPoint, pathGuidePoint); |
| | | } |
| | | double lastDistance = GeometryHelper.GetNearestDistance(new ZTLinePoint(lastPoint, obstacle[i]), point); |
| | | double lastDistance = GeoHelper.GetNearestDistance(new ZTLinePoint(lastPoint, obstacle[i]), pathGuidePoint); |
| | | if (lastDistance < distance) |
| | | { |
| | | distance = lastDistance; |
| | |
| | | } |
| | | |
| | | //查找最近离开障碍物的点 |
| | | ZTPoint testPoint = new ZTPoint(point.X, point.Y); |
| | | Int32 maxDistance = Math.Max(Math.Max(point.X, this.HousePathInfo.Width - point.X), Math.Max(point.Y, this.HousePathInfo.Height - point.Y)); |
| | | ZTPoint testPoint = ZTPoint.Empty; |
| | | Int32 maxDistance = Math.Max(Math.Max(source.X, this.HousePathInfo.Width - source.X), Math.Max(source.Y, this.HousePathInfo.Height - source.Y)); |
| | | for (int i = (Int32)distance; i < maxDistance; i++) |
| | | { |
| | | //下 |
| | | if (point.Y + i <= this.HousePathInfo.Height) |
| | | if (source.Y + i <= this.HousePathInfo.Height) |
| | | { |
| | | testPoint = new ZTPoint(point.X, point.Y + i); |
| | | if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | testPoint = new ZTPoint(source.X, source.Y + i); |
| | | if (GeoHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | { |
| | | testPoint.Y += 10; |
| | | point = testPoint; |
| | | pathGuidePoint = testPoint; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | |
| | | //右 |
| | | if (point.X <= this.HousePathInfo.Width) |
| | | if (source.X <= this.HousePathInfo.Width) |
| | | { |
| | | testPoint = new ZTPoint(point.X + i, point.Y); |
| | | if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | testPoint = new ZTPoint(source.X + i, source.Y); |
| | | if (GeoHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | { |
| | | testPoint.X += 10; |
| | | point = testPoint; |
| | | pathGuidePoint = testPoint; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | //左 |
| | | if (point.X - i >= 0) |
| | | if (source.X - i >= 0) |
| | | { |
| | | testPoint = new ZTPoint(point.X - i, point.Y); |
| | | if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | testPoint = new ZTPoint(source.X - i, source.Y); |
| | | if (GeoHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | { |
| | | testPoint.X -= 10; |
| | | point = testPoint; |
| | | pathGuidePoint = testPoint; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | //上 |
| | | if (point.Y - i >= 0) |
| | | if (source.Y - i >= 0) |
| | | { |
| | | testPoint = new ZTPoint(point.X, point.Y - i); |
| | | if (GeometryHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | testPoint = new ZTPoint(source.X, source.Y - i); |
| | | if (GeoHelper.IntersectionOf(testPoint, obstacle) == Intersection.None) |
| | | { |
| | | testPoint.Y -= 10; |
| | | point = testPoint; |
| | | pathGuidePoint = testPoint; |
| | | break; |
| | | } |
| | | } |
| | |
| | | /// <summary> |
| | | /// 初始化寻路器 |
| | | /// </summary> |
| | | private void InitPathInfo() |
| | | private void InitPathInfo(Int32[] withoutNumber) |
| | | { |
| | | this.PathFinder = new Dijkstra<ZTPoint>(); |
| | | |
| | |
| | | this.LocationDic.Add(pp.Parameter, pp.Point); |
| | | } |
| | | } |
| | | |
| | | //计算门朝向 |
| | | doorDirection = new Direction[this.HousePathInfo.NextGates.Count]; |
| | | for (Int32 i = 0; i < this.HousePathInfo.NextGates.Count; i++) |
| | | { |
| | | switch (this.HousePathInfo.NextGates[i].Parameter) |
| | | { |
| | | case 0: |
| | | doorDirection[i] = Direction.Up; |
| | | break; |
| | | case 1: |
| | | doorDirection[i] = Direction.Right; |
| | | break; |
| | | case 2: |
| | | doorDirection[i] = Direction.Bottom; |
| | | break; |
| | | case 3: |
| | | doorDirection[i] = Direction.Left; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (withoutNumber != null) |
| | | { |
| | | for (int i = 0; i < withoutNumber.Length; i++) |
| | | { |
| | | if (!this.WithoutNumber.ContainsKey(withoutNumber[i])) |
| | | { |
| | | this.WithoutNumber.Add(withoutNumber[i], true); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | point = this.HousePathInfo.FindPathPoints[i]; |
| | | if (Iscross(start, point)) |
| | | { |
| | | distance = (Int32)GeometryHelper.GetPointDistance(start, point); |
| | | distance = (Int32)GeoHelper.GetPointDistance(start, point); |
| | | this.PathFinder.AddEdge(start, point, distance); |
| | | } |
| | | |
| | | if (Iscross(end, point)) |
| | | { |
| | | distance = (Int32)GeometryHelper.GetPointDistance(end, point); |
| | | distance = (Int32)GeoHelper.GetPointDistance(end, point); |
| | | this.PathFinder.AddEdge(end, point, distance); |
| | | } |
| | | } |