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