-
- using Godot;
-
- public static class DungeonTileManager
- {
- public static void AutoFillRoomTile(TileMap floor, TileMap middle, TileMap top, AutoTileConfig config,
- RoomInfo roomInfo)
- {
- foreach (var info in roomInfo.Next)
- {
- AutoFillRoomTile(floor, middle, top, config, info);
- }
-
- //铺房间
- FillRect(floor, config.Ground, roomInfo.Position + Vector2.One, roomInfo.Size - new Vector2(2, 2));
-
- FillRect(top, config.IN_LT, roomInfo.Position, Vector2.One);
- FillRect(top, config.L, roomInfo.Position + new Vector2(0, 1), new Vector2(1, roomInfo.Size.Y - 2));
- FillRect(top, config.IN_LB, roomInfo.Position + new Vector2(0, roomInfo.Size.Y - 1), new Vector2(1, 1));
- FillRect(top, config.B, roomInfo.Position + new Vector2(1, roomInfo.Size.Y - 1),
- new Vector2(roomInfo.Size.X - 2, 1));
- FillRect(top, config.IN_RB, roomInfo.Position + new Vector2(roomInfo.Size.X - 1, roomInfo.Size.Y - 1),
- Vector2.One);
- FillRect(top, config.R, roomInfo.Position + new Vector2(roomInfo.Size.X - 1, 1),
- new Vector2(1, roomInfo.Size.Y - 2));
- FillRect(top, config.IN_RT, roomInfo.Position + new Vector2(roomInfo.Size.X - 1, 0), Vector2.One);
- FillRect(middle, config.T, roomInfo.Position + Vector2.Right, new Vector2(roomInfo.Size.X - 2, 1));
-
- //铺过道
- foreach (var doorInfo in roomInfo.Doors)
- {
- if (doorInfo.ConnectRoom.Id > roomInfo.Id)
- {
- //普通的直线连接
- var doorDir1 = doorInfo.Direction;
- var doorDir2 = doorInfo.ConnectDoor.Direction;
- if (!doorInfo.HasCross)
- {
- //方向, 0横向, 1纵向
- int dir = 0;
- var rect = Utils.CalcRect(
- doorInfo.OriginPosition.X,
- doorInfo.OriginPosition.Y,
- doorInfo.ConnectDoor.OriginPosition.X,
- doorInfo.ConnectDoor.OriginPosition.Y
- );
- if (doorDir1 == DoorDirection.N || doorDir1 == DoorDirection.S)
- {
- rect.Size = new Vector2(GenerateDungeon.CorridorWidth, rect.Size.Y);
- dir = 1;
- }
- else
- {
- rect.Size = new Vector2(rect.Size.X, GenerateDungeon.CorridorWidth);
- }
-
- if (dir == 0) //横向
- {
- FullHorizontalGalleryWall(floor, middle, top, config, rect);
- }
- else //纵向
- {
- FullVerticalGalleryWall(floor, middle, top, config, rect);
- }
- }
- else //带交叉点
- {
- //方向, 0横向, 1纵向
- int dir1 = 0;
- int dir2 = 0;
-
- Rect2 rect;
- Rect2 rect2;
-
- //计算范围
- switch (doorDir1)
- {
- case DoorDirection.E: //→
- rect = new Rect2(
- doorInfo.OriginPosition.X,
- doorInfo.OriginPosition.Y,
- doorInfo.Cross.X - doorInfo.OriginPosition.X,
- GenerateDungeon.CorridorWidth
- );
- break;
- case DoorDirection.W: //←
- rect = new Rect2(
- doorInfo.Cross.X + GenerateDungeon.CorridorWidth,
- doorInfo.Cross.Y,
- doorInfo.OriginPosition.X - (doorInfo.Cross.X + GenerateDungeon.CorridorWidth),
- GenerateDungeon.CorridorWidth
- );
- break;
- case DoorDirection.S: //↓
- dir1 = 1;
- rect = new Rect2(
- doorInfo.OriginPosition.X,
- doorInfo.OriginPosition.Y,
- GenerateDungeon.CorridorWidth,
- doorInfo.Cross.Y - doorInfo.OriginPosition.Y
- );
- break;
- case DoorDirection.N: //↑
- dir1 = 1;
- rect = new Rect2(
- doorInfo.Cross.X,
- doorInfo.Cross.Y + GenerateDungeon.CorridorWidth,
- GenerateDungeon.CorridorWidth,
- doorInfo.OriginPosition.Y - (doorInfo.Cross.Y + GenerateDungeon.CorridorWidth)
- );
- break;
- default:
- rect = new Rect2();
- break;
- }
-
- switch (doorDir2)
- {
- case DoorDirection.E: //→
- rect2 = new Rect2(
- doorInfo.ConnectDoor.OriginPosition.X,
- doorInfo.ConnectDoor.OriginPosition.Y,
- doorInfo.Cross.X - doorInfo.ConnectDoor.OriginPosition.X,
- GenerateDungeon.CorridorWidth
- );
- break;
- case DoorDirection.W: //←
- rect2 = new Rect2(
- doorInfo.Cross.X + GenerateDungeon.CorridorWidth,
- doorInfo.Cross.Y,
- doorInfo.ConnectDoor.OriginPosition.X - (doorInfo.Cross.X + GenerateDungeon.CorridorWidth),
- GenerateDungeon.CorridorWidth
- );
- break;
- case DoorDirection.S: //↓
- dir2 = 1;
- rect2 = new Rect2(
- doorInfo.ConnectDoor.OriginPosition.X,
- doorInfo.ConnectDoor.OriginPosition.Y,
- GenerateDungeon.CorridorWidth,
- doorInfo.Cross.Y - doorInfo.ConnectDoor.OriginPosition.Y
- );
- break;
- case DoorDirection.N: //↑
- dir2 = 1;
- rect2 = new Rect2(
- doorInfo.Cross.X,
- doorInfo.Cross.Y + GenerateDungeon.CorridorWidth,
- GenerateDungeon.CorridorWidth,
- doorInfo.ConnectDoor.OriginPosition.Y - (doorInfo.Cross.Y + GenerateDungeon.CorridorWidth)
- );
- break;
- default:
- rect2 = new Rect2();
- break;
- }
-
- FillRect(floor, config.Ground, doorInfo.Cross + Vector2.One,
- new Vector2(GenerateDungeon.CorridorWidth - 2, GenerateDungeon.CorridorWidth - 2));
-
- //墙壁
- if (dir1 == 0)
- {
- FullHorizontalGalleryWall(floor, middle, top, config, rect);
- }
- else
- {
- FullVerticalGalleryWall(floor, middle, top, config, rect);
- }
- if (dir2 == 0)
- {
- FullHorizontalGalleryWall(floor, middle, top, config, rect2);
- }
- else
- {
- FullVerticalGalleryWall(floor, middle, top, config, rect2);
- }
-
- if ((doorDir1 == DoorDirection.N && doorDir2 == DoorDirection.E) || //↑→
- (doorDir2 == DoorDirection.N && doorDir1 == DoorDirection.E))
- {
- FillRect(top, config.OUT_RT,
- doorInfo.Cross + new Vector2(0, GenerateDungeon.CorridorWidth - 1),
- Vector2.One);
- FillRect(top, config.IN_RT, doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, 0), Vector2.One);
- FillRect(middle, config.T, doorInfo.Cross, new Vector2(GenerateDungeon.CorridorWidth - 1, 1));
- FillRect(top, config.R, doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, 1),
- new Vector2(1, GenerateDungeon.CorridorWidth - 1));
- }
- else if ((doorDir1 == DoorDirection.E && doorDir2 == DoorDirection.S) || //→↓
- (doorDir2 == DoorDirection.E && doorDir1 == DoorDirection.S))
- {
- FillRect(middle, config.OUT_RB, doorInfo.Cross, Vector2.One);
- FillRect(top, config.IN_RB, doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, GenerateDungeon.CorridorWidth - 1),
- Vector2.One);
- FillRect(top, config.R, doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, 0),
- new Vector2(1, GenerateDungeon.CorridorWidth - 1));
- FillRect(top, config.B, doorInfo.Cross + new Vector2(0, GenerateDungeon.CorridorWidth - 1),
- new Vector2(GenerateDungeon.CorridorWidth - 1, 1));
- }
- else if ((doorDir1 == DoorDirection.S && doorDir2 == DoorDirection.W) || //↓←
- (doorDir2 == DoorDirection.S && doorDir1 == DoorDirection.W))
- {
- FillRect(middle, config.OUT_LB,
- doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, 0), Vector2.One);
- FillRect(top, config.IN_LB, doorInfo.Cross + new Vector2(0, GenerateDungeon.CorridorWidth - 1),
- Vector2.One);
- FillRect(top, config.L, doorInfo.Cross, new Vector2(1, GenerateDungeon.CorridorWidth - 1));
- FillRect(top, config.B, doorInfo.Cross + new Vector2(1, GenerateDungeon.CorridorWidth - 1),
- new Vector2(GenerateDungeon.CorridorWidth - 1, 1));
- }
- else if ((doorDir1 == DoorDirection.W && doorDir2 == DoorDirection.N) || //←↑
- (doorDir2 == DoorDirection.W && doorDir1 == DoorDirection.N))
- {
- FillRect(top, config.OUT_LT,
- doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, GenerateDungeon.CorridorWidth - 1),
- Vector2.One);
- FillRect(top, config.IN_LT, doorInfo.Cross, Vector2.One);
- FillRect(middle, config.T, doorInfo.Cross + new Vector2(1, 0),
- new Vector2(GenerateDungeon.CorridorWidth - 1, 1));
- FillRect(top, config.L, doorInfo.Cross + new Vector2(0, 1),
- new Vector2(1, GenerateDungeon.CorridorWidth - 1));
- }
-
- //在房间墙上开洞
- switch (doorDir1)
- {
- case DoorDirection.E: //→
- ClearRect(top, doorInfo.OriginPosition + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2));
- FillRect(floor, config.Ground, doorInfo.OriginPosition + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2));
- break;
- case DoorDirection.W: //←
- ClearRect(top, doorInfo.OriginPosition + new Vector2(0, 1), new Vector2(1, rect.Size.Y - 2));
- FillRect(floor, config.Ground, doorInfo.OriginPosition + new Vector2(0, 1), new Vector2(1, rect.Size.Y - 2));
- break;
- case DoorDirection.S: //↓
- ClearRect(top, doorInfo.OriginPosition + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1));
- FillRect(floor, config.Ground, doorInfo.OriginPosition + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1));
- break;
- case DoorDirection.N: //↑
- ClearRect(middle, doorInfo.OriginPosition + new Vector2(1, 2), new Vector2(rect.Size.X - 2, 1));
- FillRect(floor, config.Ground, doorInfo.OriginPosition + new Vector2(1, 0), new Vector2(rect.Size.X - 2, 1));
- break;
- }
- switch (doorDir2)
- {
- case DoorDirection.E: //→
- ClearRect(top, doorInfo.ConnectDoor.OriginPosition + new Vector2(-1, 1), new Vector2(1, rect2.Size.Y - 2));
- FillRect(floor, config.Ground, doorInfo.ConnectDoor.OriginPosition + new Vector2(-1, 1), new Vector2(1, rect2.Size.Y - 2));
- break;
- case DoorDirection.W: //←
- ClearRect(top, doorInfo.ConnectDoor.OriginPosition + new Vector2(0, 1), new Vector2(1, rect2.Size.Y - 2));
- FillRect(floor, config.Ground, doorInfo.ConnectDoor.OriginPosition + new Vector2(0, 1), new Vector2(1, rect2.Size.Y - 2));
- break;
- case DoorDirection.S: //↓
- ClearRect(top, doorInfo.ConnectDoor.OriginPosition + new Vector2(1, -1), new Vector2(rect2.Size.X - 2, 1));
- FillRect(floor, config.Ground, doorInfo.ConnectDoor.OriginPosition + new Vector2(1, -1), new Vector2(rect2.Size.X - 2, 1));
- break;
- case DoorDirection.N: //↑
- ClearRect(middle, doorInfo.ConnectDoor.OriginPosition + new Vector2(1, 0), new Vector2(rect2.Size.X - 2, 1));
- FillRect(floor, config.Ground, doorInfo.ConnectDoor.OriginPosition + new Vector2(1, 0), new Vector2(rect2.Size.X - 2, 1));
- break;
- }
- }
- }
- }
- }
-
- private static void FillRect(TileMap tileMap, TileCellInfo info, Vector2 pos, Vector2 size)
- {
- for (int i = 0; i < size.X; i++)
- {
- for (int j = 0; j < size.Y; j++)
- {
- //tileMap.SetCell((int)pos.X + i, (int)pos.Y + j, info.Id, false, false, false, info.AutotileCoord);
- }
- }
- }
-
- private static void ClearRect(TileMap tileMap, Vector2 pos, Vector2 size)
- {
- for (int i = 0; i < size.X; i++)
- {
- for (int j = 0; j < size.Y; j++)
- {
- //tileMap.SetCell((int)pos.X + i, (int)pos.Y + j, -1);
- }
- }
- }
-
- private static void FullHorizontalGalleryWall(TileMap floor, TileMap middle, TileMap top, AutoTileConfig config, Rect2 rect)
- {
- FillRect(floor, config.Ground, rect.Position + new Vector2(0, 1), rect.Size - new Vector2(0, 2));
- FillRect(middle, config.T, rect.Position, new Vector2(rect.Size.X, 1));
- FillRect(top, config.B, rect.Position + new Vector2(0, rect.Size.Y - 1), new Vector2(rect.Size.X, 1));
- //左
- ClearRect(top, rect.Position + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2));
- FillRect(floor, config.Ground, rect.Position + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2));
- //右
- ClearRect(top, rect.Position + new Vector2(rect.Size.X, 1), new Vector2(1, rect.Size.Y - 2));
- FillRect(floor, config.Ground, rect.Position + new Vector2(rect.Size.X, 1), new Vector2(1, rect.Size.Y - 2));
- }
-
- private static void FullVerticalGalleryWall(TileMap floor, TileMap middle, TileMap top, AutoTileConfig config, Rect2 rect)
- {
- FillRect(floor, config.Ground, rect.Position + new Vector2(1, 0), rect.Size - new Vector2(2, 0));
- FillRect(top, config.L, rect.Position, new Vector2(1, rect.Size.Y));
- FillRect(top, config.R, rect.Position + new Vector2(rect.Size.X - 1, 0), new Vector2(1, rect.Size.Y));
- //上
- ClearRect(top, rect.Position + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1));
- FillRect(floor, config.Ground, rect.Position + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1));
- //下
- ClearRect(middle, rect.Position + new Vector2(1, rect.Size.Y), new Vector2(rect.Size.X - 2, 1));
- FillRect(floor, config.Ground, rect.Position + new Vector2(1, rect.Size.Y), new Vector2(rect.Size.X - 2, 1));
- }
-
- }