Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / room / DungeonTileManager.cs
  1.  
  2. using Godot;
  3.  
  4. public static class DungeonTileManager
  5. {
  6. public static void AutoFillRoomTile(TileMap floor, TileMap middle, TileMap top, AutoTileConfig config,
  7. RoomInfo roomInfo)
  8. {
  9. foreach (var info in roomInfo.Next)
  10. {
  11. AutoFillRoomTile(floor, middle, top, config, info);
  12. }
  13.  
  14. //铺房间
  15. FillRect(floor, config.Ground, roomInfo.Position + Vector2.One, roomInfo.Size - new Vector2(2, 2));
  16.  
  17. FillRect(top, config.IN_LT, roomInfo.Position, Vector2.One);
  18. FillRect(top, config.L, roomInfo.Position + new Vector2(0, 1), new Vector2(1, roomInfo.Size.Y - 2));
  19. FillRect(top, config.IN_LB, roomInfo.Position + new Vector2(0, roomInfo.Size.Y - 1), new Vector2(1, 1));
  20. FillRect(top, config.B, roomInfo.Position + new Vector2(1, roomInfo.Size.Y - 1),
  21. new Vector2(roomInfo.Size.X - 2, 1));
  22. FillRect(top, config.IN_RB, roomInfo.Position + new Vector2(roomInfo.Size.X - 1, roomInfo.Size.Y - 1),
  23. Vector2.One);
  24. FillRect(top, config.R, roomInfo.Position + new Vector2(roomInfo.Size.X - 1, 1),
  25. new Vector2(1, roomInfo.Size.Y - 2));
  26. FillRect(top, config.IN_RT, roomInfo.Position + new Vector2(roomInfo.Size.X - 1, 0), Vector2.One);
  27. FillRect(middle, config.T, roomInfo.Position + Vector2.Right, new Vector2(roomInfo.Size.X - 2, 1));
  28.  
  29. //铺过道
  30. foreach (var doorInfo in roomInfo.Doors)
  31. {
  32. if (doorInfo.ConnectRoom.Id > roomInfo.Id)
  33. {
  34. //普通的直线连接
  35. var doorDir1 = doorInfo.Direction;
  36. var doorDir2 = doorInfo.ConnectDoor.Direction;
  37. if (!doorInfo.HasCross)
  38. {
  39. //方向, 0横向, 1纵向
  40. int dir = 0;
  41. var rect = Utils.CalcRect(
  42. doorInfo.OriginPosition.X,
  43. doorInfo.OriginPosition.Y,
  44. doorInfo.ConnectDoor.OriginPosition.X,
  45. doorInfo.ConnectDoor.OriginPosition.Y
  46. );
  47. if (doorDir1 == DoorDirection.N || doorDir1 == DoorDirection.S)
  48. {
  49. rect.Size = new Vector2(GenerateDungeon.CorridorWidth, rect.Size.Y);
  50. dir = 1;
  51. }
  52. else
  53. {
  54. rect.Size = new Vector2(rect.Size.X, GenerateDungeon.CorridorWidth);
  55. }
  56.  
  57. if (dir == 0) //横向
  58. {
  59. FullHorizontalGalleryWall(floor, middle, top, config, rect);
  60. }
  61. else //纵向
  62. {
  63. FullVerticalGalleryWall(floor, middle, top, config, rect);
  64. }
  65. }
  66. else //带交叉点
  67. {
  68. //方向, 0横向, 1纵向
  69. int dir1 = 0;
  70. int dir2 = 0;
  71.  
  72. Rect2 rect;
  73. Rect2 rect2;
  74.  
  75. //计算范围
  76. switch (doorDir1)
  77. {
  78. case DoorDirection.E: //→
  79. rect = new Rect2(
  80. doorInfo.OriginPosition.X,
  81. doorInfo.OriginPosition.Y,
  82. doorInfo.Cross.X - doorInfo.OriginPosition.X,
  83. GenerateDungeon.CorridorWidth
  84. );
  85. break;
  86. case DoorDirection.W: //←
  87. rect = new Rect2(
  88. doorInfo.Cross.X + GenerateDungeon.CorridorWidth,
  89. doorInfo.Cross.Y,
  90. doorInfo.OriginPosition.X - (doorInfo.Cross.X + GenerateDungeon.CorridorWidth),
  91. GenerateDungeon.CorridorWidth
  92. );
  93. break;
  94. case DoorDirection.S: //↓
  95. dir1 = 1;
  96. rect = new Rect2(
  97. doorInfo.OriginPosition.X,
  98. doorInfo.OriginPosition.Y,
  99. GenerateDungeon.CorridorWidth,
  100. doorInfo.Cross.Y - doorInfo.OriginPosition.Y
  101. );
  102. break;
  103. case DoorDirection.N: //↑
  104. dir1 = 1;
  105. rect = new Rect2(
  106. doorInfo.Cross.X,
  107. doorInfo.Cross.Y + GenerateDungeon.CorridorWidth,
  108. GenerateDungeon.CorridorWidth,
  109. doorInfo.OriginPosition.Y - (doorInfo.Cross.Y + GenerateDungeon.CorridorWidth)
  110. );
  111. break;
  112. default:
  113. rect = new Rect2();
  114. break;
  115. }
  116. switch (doorDir2)
  117. {
  118. case DoorDirection.E: //→
  119. rect2 = new Rect2(
  120. doorInfo.ConnectDoor.OriginPosition.X,
  121. doorInfo.ConnectDoor.OriginPosition.Y,
  122. doorInfo.Cross.X - doorInfo.ConnectDoor.OriginPosition.X,
  123. GenerateDungeon.CorridorWidth
  124. );
  125. break;
  126. case DoorDirection.W: //←
  127. rect2 = new Rect2(
  128. doorInfo.Cross.X + GenerateDungeon.CorridorWidth,
  129. doorInfo.Cross.Y,
  130. doorInfo.ConnectDoor.OriginPosition.X - (doorInfo.Cross.X + GenerateDungeon.CorridorWidth),
  131. GenerateDungeon.CorridorWidth
  132. );
  133. break;
  134. case DoorDirection.S: //↓
  135. dir2 = 1;
  136. rect2 = new Rect2(
  137. doorInfo.ConnectDoor.OriginPosition.X,
  138. doorInfo.ConnectDoor.OriginPosition.Y,
  139. GenerateDungeon.CorridorWidth,
  140. doorInfo.Cross.Y - doorInfo.ConnectDoor.OriginPosition.Y
  141. );
  142. break;
  143. case DoorDirection.N: //↑
  144. dir2 = 1;
  145. rect2 = new Rect2(
  146. doorInfo.Cross.X,
  147. doorInfo.Cross.Y + GenerateDungeon.CorridorWidth,
  148. GenerateDungeon.CorridorWidth,
  149. doorInfo.ConnectDoor.OriginPosition.Y - (doorInfo.Cross.Y + GenerateDungeon.CorridorWidth)
  150. );
  151. break;
  152. default:
  153. rect2 = new Rect2();
  154. break;
  155. }
  156.  
  157. FillRect(floor, config.Ground, doorInfo.Cross + Vector2.One,
  158. new Vector2(GenerateDungeon.CorridorWidth - 2, GenerateDungeon.CorridorWidth - 2));
  159.  
  160. //墙壁
  161. if (dir1 == 0)
  162. {
  163. FullHorizontalGalleryWall(floor, middle, top, config, rect);
  164. }
  165. else
  166. {
  167. FullVerticalGalleryWall(floor, middle, top, config, rect);
  168. }
  169. if (dir2 == 0)
  170. {
  171. FullHorizontalGalleryWall(floor, middle, top, config, rect2);
  172. }
  173. else
  174. {
  175. FullVerticalGalleryWall(floor, middle, top, config, rect2);
  176. }
  177.  
  178. if ((doorDir1 == DoorDirection.N && doorDir2 == DoorDirection.E) || //↑→
  179. (doorDir2 == DoorDirection.N && doorDir1 == DoorDirection.E))
  180. {
  181. FillRect(top, config.OUT_RT,
  182. doorInfo.Cross + new Vector2(0, GenerateDungeon.CorridorWidth - 1),
  183. Vector2.One);
  184. FillRect(top, config.IN_RT, doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, 0), Vector2.One);
  185. FillRect(middle, config.T, doorInfo.Cross, new Vector2(GenerateDungeon.CorridorWidth - 1, 1));
  186. FillRect(top, config.R, doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, 1),
  187. new Vector2(1, GenerateDungeon.CorridorWidth - 1));
  188. }
  189. else if ((doorDir1 == DoorDirection.E && doorDir2 == DoorDirection.S) || //→↓
  190. (doorDir2 == DoorDirection.E && doorDir1 == DoorDirection.S))
  191. {
  192. FillRect(middle, config.OUT_RB, doorInfo.Cross, Vector2.One);
  193. FillRect(top, config.IN_RB, doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, GenerateDungeon.CorridorWidth - 1),
  194. Vector2.One);
  195. FillRect(top, config.R, doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, 0),
  196. new Vector2(1, GenerateDungeon.CorridorWidth - 1));
  197. FillRect(top, config.B, doorInfo.Cross + new Vector2(0, GenerateDungeon.CorridorWidth - 1),
  198. new Vector2(GenerateDungeon.CorridorWidth - 1, 1));
  199. }
  200. else if ((doorDir1 == DoorDirection.S && doorDir2 == DoorDirection.W) || //↓←
  201. (doorDir2 == DoorDirection.S && doorDir1 == DoorDirection.W))
  202. {
  203. FillRect(middle, config.OUT_LB,
  204. doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, 0), Vector2.One);
  205. FillRect(top, config.IN_LB, doorInfo.Cross + new Vector2(0, GenerateDungeon.CorridorWidth - 1),
  206. Vector2.One);
  207. FillRect(top, config.L, doorInfo.Cross, new Vector2(1, GenerateDungeon.CorridorWidth - 1));
  208. FillRect(top, config.B, doorInfo.Cross + new Vector2(1, GenerateDungeon.CorridorWidth - 1),
  209. new Vector2(GenerateDungeon.CorridorWidth - 1, 1));
  210. }
  211. else if ((doorDir1 == DoorDirection.W && doorDir2 == DoorDirection.N) || //←↑
  212. (doorDir2 == DoorDirection.W && doorDir1 == DoorDirection.N))
  213. {
  214. FillRect(top, config.OUT_LT,
  215. doorInfo.Cross + new Vector2(GenerateDungeon.CorridorWidth - 1, GenerateDungeon.CorridorWidth - 1),
  216. Vector2.One);
  217. FillRect(top, config.IN_LT, doorInfo.Cross, Vector2.One);
  218. FillRect(middle, config.T, doorInfo.Cross + new Vector2(1, 0),
  219. new Vector2(GenerateDungeon.CorridorWidth - 1, 1));
  220. FillRect(top, config.L, doorInfo.Cross + new Vector2(0, 1),
  221. new Vector2(1, GenerateDungeon.CorridorWidth - 1));
  222. }
  223. //在房间墙上开洞
  224. switch (doorDir1)
  225. {
  226. case DoorDirection.E: //→
  227. ClearRect(top, doorInfo.OriginPosition + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2));
  228. FillRect(floor, config.Ground, doorInfo.OriginPosition + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2));
  229. break;
  230. case DoorDirection.W: //←
  231. ClearRect(top, doorInfo.OriginPosition + new Vector2(0, 1), new Vector2(1, rect.Size.Y - 2));
  232. FillRect(floor, config.Ground, doorInfo.OriginPosition + new Vector2(0, 1), new Vector2(1, rect.Size.Y - 2));
  233. break;
  234. case DoorDirection.S: //↓
  235. ClearRect(top, doorInfo.OriginPosition + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1));
  236. FillRect(floor, config.Ground, doorInfo.OriginPosition + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1));
  237. break;
  238. case DoorDirection.N: //↑
  239. ClearRect(middle, doorInfo.OriginPosition + new Vector2(1, 2), new Vector2(rect.Size.X - 2, 1));
  240. FillRect(floor, config.Ground, doorInfo.OriginPosition + new Vector2(1, 0), new Vector2(rect.Size.X - 2, 1));
  241. break;
  242. }
  243. switch (doorDir2)
  244. {
  245. case DoorDirection.E: //→
  246. ClearRect(top, doorInfo.ConnectDoor.OriginPosition + new Vector2(-1, 1), new Vector2(1, rect2.Size.Y - 2));
  247. FillRect(floor, config.Ground, doorInfo.ConnectDoor.OriginPosition + new Vector2(-1, 1), new Vector2(1, rect2.Size.Y - 2));
  248. break;
  249. case DoorDirection.W: //←
  250. ClearRect(top, doorInfo.ConnectDoor.OriginPosition + new Vector2(0, 1), new Vector2(1, rect2.Size.Y - 2));
  251. FillRect(floor, config.Ground, doorInfo.ConnectDoor.OriginPosition + new Vector2(0, 1), new Vector2(1, rect2.Size.Y - 2));
  252. break;
  253. case DoorDirection.S: //↓
  254. ClearRect(top, doorInfo.ConnectDoor.OriginPosition + new Vector2(1, -1), new Vector2(rect2.Size.X - 2, 1));
  255. FillRect(floor, config.Ground, doorInfo.ConnectDoor.OriginPosition + new Vector2(1, -1), new Vector2(rect2.Size.X - 2, 1));
  256. break;
  257. case DoorDirection.N: //↑
  258. ClearRect(middle, doorInfo.ConnectDoor.OriginPosition + new Vector2(1, 0), new Vector2(rect2.Size.X - 2, 1));
  259. FillRect(floor, config.Ground, doorInfo.ConnectDoor.OriginPosition + new Vector2(1, 0), new Vector2(rect2.Size.X - 2, 1));
  260. break;
  261. }
  262. }
  263. }
  264. }
  265. }
  266.  
  267. private static void FillRect(TileMap tileMap, TileCellInfo info, Vector2 pos, Vector2 size)
  268. {
  269. for (int i = 0; i < size.X; i++)
  270. {
  271. for (int j = 0; j < size.Y; j++)
  272. {
  273. //tileMap.SetCell((int)pos.X + i, (int)pos.Y + j, info.Id, false, false, false, info.AutotileCoord);
  274. }
  275. }
  276. }
  277.  
  278. private static void ClearRect(TileMap tileMap, Vector2 pos, Vector2 size)
  279. {
  280. for (int i = 0; i < size.X; i++)
  281. {
  282. for (int j = 0; j < size.Y; j++)
  283. {
  284. //tileMap.SetCell((int)pos.X + i, (int)pos.Y + j, -1);
  285. }
  286. }
  287. }
  288.  
  289. private static void FullHorizontalGalleryWall(TileMap floor, TileMap middle, TileMap top, AutoTileConfig config, Rect2 rect)
  290. {
  291. FillRect(floor, config.Ground, rect.Position + new Vector2(0, 1), rect.Size - new Vector2(0, 2));
  292. FillRect(middle, config.T, rect.Position, new Vector2(rect.Size.X, 1));
  293. FillRect(top, config.B, rect.Position + new Vector2(0, rect.Size.Y - 1), new Vector2(rect.Size.X, 1));
  294. //左
  295. ClearRect(top, rect.Position + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2));
  296. FillRect(floor, config.Ground, rect.Position + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2));
  297. //右
  298. ClearRect(top, rect.Position + new Vector2(rect.Size.X, 1), new Vector2(1, rect.Size.Y - 2));
  299. FillRect(floor, config.Ground, rect.Position + new Vector2(rect.Size.X, 1), new Vector2(1, rect.Size.Y - 2));
  300. }
  301.  
  302. private static void FullVerticalGalleryWall(TileMap floor, TileMap middle, TileMap top, AutoTileConfig config, Rect2 rect)
  303. {
  304. FillRect(floor, config.Ground, rect.Position + new Vector2(1, 0), rect.Size - new Vector2(2, 0));
  305. FillRect(top, config.L, rect.Position, new Vector2(1, rect.Size.Y));
  306. FillRect(top, config.R, rect.Position + new Vector2(rect.Size.X - 1, 0), new Vector2(1, rect.Size.Y));
  307. //上
  308. ClearRect(top, rect.Position + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1));
  309. FillRect(floor, config.Ground, rect.Position + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1));
  310. //下
  311. ClearRect(middle, rect.Position + new Vector2(1, rect.Size.Y), new Vector2(rect.Size.X - 2, 1));
  312. FillRect(floor, config.Ground, rect.Position + new Vector2(1, rect.Size.Y), new Vector2(rect.Size.X - 2, 1));
  313. }
  314.  
  315. }