public DungeonPath() { Width = 1; IsHorizontal = true; Portals = new DungeonPortal[2]; Accessible = false; steps = new List<int>(); }
/// <summary> /// 2つのポータルの水平距離が垂直距離より長いか /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <returns></returns> bool IsHorizontalPortals(DungeonPortal start, DungeonPortal end) { var length = new Point(); length.X = Math.Abs(start.Position.X - end.Position.X); length.Y = Math.Abs(start.Position.Y - end.Position.Y); return length.X >= length.Y; }
/// <summary> /// 消えた部屋につながっていた袋小路の処理 /// </summary> /// <param name="room"></param> void ProcessDeadEnd(DungeonRoom room) { var deadends = new List<DungeonPath>(); UpdateAccessibility(); foreach (var portal in room.Portals) { if (portal.ConnectedPaths.Count == 0) continue; var path = portal.ConnectedPaths[0]; if (path.Accessible) { // 袋小路をリストアップ deadends.Add(path); } else { // 孤立している通路は消す RemovePath(path); } } var selector = new RandomSelector<DeadEndDisposal>(Rand); selector.Add(40, DeadEndDisposal.CONNECT); selector.Add(55, DeadEndDisposal.REMOVE); selector.Add(5, DeadEndDisposal.LEAVE); while (deadends.Count > 0) { var disposal = selector.Get(); if (disposal == DeadEndDisposal.CONNECT && deadends.Count >= 2) { var another = Rand.Next(1, deadends.Count); var portals = new DungeonPortal[2]{ deadends[0].GetTerminalPortal(), deadends[another].GetTerminalPortal() }; var path = GeneratePath( portals[0], portals[1], IsHorizontalPortals(portals[0], portals[1]) ); if (path != null) { AddPath(path); deadends.RemoveAt(another); } deadends.RemoveAt(0); } else if (disposal == DeadEndDisposal.REMOVE) { RemovePath(deadends[0]); deadends.RemoveAt(0); } else if (disposal == DeadEndDisposal.LEAVE) { deadends.RemoveAt(0); } } }
/// <summary> /// 2つのポータルの間をつなぐ通路を生成 /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="isHorizontal"></param> /// <returns></returns> DungeonPath GeneratePath(DungeonPortal start, DungeonPortal end, bool isHorizontal) { var result = new DungeonPath() { Rand = this.Rand }; start.ConnectedPaths.Add(result); result.Portals[0] = start; end.ConnectedPaths.Add(result); result.Portals[1] = end; result.IsHorizontal = isHorizontal; if (!result.GenerateSteps()) { start.ConnectedPaths.Remove(result); end.ConnectedPaths.Remove(result); result = null; } return result; }
/// <summary> /// 隣同士の部屋をつなぐためのポータル(出入口)のペアを生成 /// </summary> void GenerateRoomPortals( DungeonRoom startRoom, DungeonRoom endRoom, bool isHorizontal, out DungeonPortal startPortal, out DungeonPortal endPortal) { startPortal = new DungeonPortal( startRoom.GetRandomPortalPoint(isHorizontal ? DungeonRoom.Side.Right : DungeonRoom.Side.Bottom)); startPortal.ConnectedRoom = startRoom; startRoom.Portals.Add(startPortal); endPortal = new DungeonPortal( endRoom.GetRandomPortalPoint(isHorizontal ? DungeonRoom.Side.Left : DungeonRoom.Side.Top)); endPortal.ConnectedRoom = endRoom; endRoom.Portals.Add(endPortal); }
/// <summary> /// 隣同士の部屋をつなぐ通路を生成 /// </summary> void GenerateRoomPaths(DungeonRoom startRoom, DungeonRoom endRoom, bool isHorizontal) { var portals = new DungeonPortal[2]; GenerateRoomPortals( startRoom, endRoom, isHorizontal, out portals[0], out portals[1]); Paths.Add(GeneratePath(portals[0], portals[1], isHorizontal)); Portals.Add(portals[0]); Portals.Add(portals[1]); }