Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / room / RoomManager.cs
@小李xl 小李xl on 9 Mar 2023 10 KB 添加武器生成标记
  1. using System;
  2. using System.Collections.Generic;
  3. using Godot;
  4.  
  5. /// <summary>
  6. /// 房间管理器
  7. /// </summary>
  8. public partial class RoomManager : Node2D
  9. {
  10. /// <summary>
  11. /// //对象根节点
  12. /// </summary>
  13. [Export] public Node2D NormalLayer;
  14. /// <summary>
  15. /// 对象根节点, 带y轴排序功能
  16. /// </summary>
  17. [Export] public Node2D YSortLayer;
  18. /// <summary>
  19. /// 地图根节点
  20. /// </summary>
  21. [Export] public TileMap TileRoot;
  22.  
  23. /// <summary>
  24. /// 玩家对象
  25. /// </summary>
  26. public Player Player { get; private set; }
  27.  
  28. /// <summary>
  29. /// 当前玩家所在的房间
  30. /// </summary>
  31. public RoomInfo ActiveRoom => Player?.Affiliation.RoomInfo;
  32. /// <summary>
  33. /// 当前玩家所在的区域
  34. /// </summary>
  35. public AffiliationArea ActiveAffiliation => Player?.Affiliation;
  36. private DungeonTile _dungeonTile;
  37. private AutoTileConfig _autoTileConfig;
  38. private Font _font;
  39. private GenerateDungeon _generateDungeon;
  40.  
  41. private int _affiliationIndex = 0;
  42.  
  43. //房间内所有静态导航网格数据
  44. private static List<NavigationPolygonData> _roomStaticNavigationList = new List<NavigationPolygonData>();
  45. public override void _Ready()
  46. {
  47. TileRoot.YSortEnabled = false;
  48. _font = ResourceManager.Load<Font>(ResourcePath.resource_font_cn_font_36_tres);
  49.  
  50. //绑定事件
  51. EventManager.AddEventListener(EventEnum.OnEnemyDie, OnEnemyDie);
  52. EventManager.AddEventListener(EventEnum.OnPlayerFirstEnterRoom, OnPlayerFirstEnterRoom);
  53. EventManager.AddEventListener(EventEnum.OnPlayerEnterRoom, OnPlayerEnterRoom);
  54. var nowTicks = DateTime.Now.Ticks;
  55. //生成地牢房间
  56. _generateDungeon = new GenerateDungeon();
  57. _generateDungeon.Generate();
  58. //填充地牢
  59. _autoTileConfig = new AutoTileConfig();
  60. _dungeonTile = new DungeonTile(TileRoot);
  61. _dungeonTile.AutoFillRoomTile(_autoTileConfig, _generateDungeon.StartRoom);
  62. //生成寻路网格, 这一步操作只生成过道的导航
  63. _dungeonTile.GenerateNavigationPolygon(DungeonTile.AisleFloorMapLayer);
  64. //挂载过道导航区域
  65. _dungeonTile.MountNavigationPolygon(this);
  66. //过道导航区域数据
  67. _roomStaticNavigationList.AddRange(_dungeonTile.GetPolygonData());
  68. //门导航区域数据
  69. _roomStaticNavigationList.AddRange(_dungeonTile.GetConnectDoorPolygonData());
  70. //初始化所有房间
  71. _generateDungeon.EachRoom(InitRoom);
  72.  
  73. GD.Print("生成地牢用时: " + (DateTime.Now.Ticks - nowTicks) / 10000 + "毫秒");
  74.  
  75. //播放bgm
  76. //SoundManager.PlayMusic(ResourcePath.resource_sound_bgm_Intro_ogg, -17f);
  77.  
  78. //创建玩家
  79. Player = ActivityObject.Create<Player>(ActivityIdPrefix.Role + "0001");
  80. Player.Position = new Vector2(30, 30);
  81. Player.Name = "Player";
  82. Player.PutDown(RoomLayerEnum.YSortLayer);
  83. Player.PickUpWeapon(ActivityObject.Create<Weapon>(ActivityIdPrefix.Weapon + "0001"));
  84. // Player.PickUpWeapon(ActivityObject.Create<Weapon>(ActivityIdPrefix.Weapon + "0002"));
  85. // Player.PickUpWeapon(ActivityObject.Create<Weapon>(ActivityIdPrefix.Weapon + "0004"));
  86. // Player.PickUpWeapon(ActivityObject.Create<Weapon>(ActivityIdPrefix.Weapon + "0003"));
  87.  
  88. //相机跟随玩家
  89. GameCamera.Main.SetFollowTarget(Player);
  90. //修改鼠标指针
  91. var cursor = GameApplication.Instance.Cursor;
  92. cursor.SetGuiMode(false);
  93. cursor.SetMountRole(Player);
  94. }
  95.  
  96. /// <summary>
  97. /// 获取指定层级根节点
  98. /// </summary>
  99. public Node2D GetRoomLayer(RoomLayerEnum layerEnum)
  100. {
  101. switch (layerEnum)
  102. {
  103. case RoomLayerEnum.NormalLayer:
  104. return NormalLayer;
  105. case RoomLayerEnum.YSortLayer:
  106. return YSortLayer;
  107. }
  108.  
  109. return null;
  110. }
  111.  
  112. public override void _Process(double delta)
  113. {
  114. Enemy.UpdateEnemiesView();
  115. if (GameApplication.Instance.Debug)
  116. {
  117. QueueRedraw();
  118. }
  119. }
  120.  
  121. public override void _Draw()
  122. {
  123. if (GameApplication.Instance.Debug)
  124. {
  125. if (_dungeonTile != null)
  126. {
  127. //绘制ai寻路区域
  128. Utils.DrawNavigationPolygon(this, _roomStaticNavigationList.ToArray());
  129. }
  130. //绘制房间区域
  131. //DrawRoomInfo(_generateDungeon.StartRoom);
  132. }
  133. }
  134.  
  135. // 初始化房间
  136. private void InitRoom(RoomInfo roomInfo)
  137. {
  138. //挂载房间导航区域
  139. MountNavFromRoomInfo(roomInfo);
  140. //创建门
  141. CreateDoor(roomInfo);
  142. //创建房间归属区域
  143. CreateRoomAisleAffiliation(roomInfo);
  144. }
  145. //挂载房间导航区域
  146. private void MountNavFromRoomInfo(RoomInfo roomInfo)
  147. {
  148. var polygonArray = roomInfo.RoomSplit.RoomInfo.NavigationList.ToArray();
  149. var polygon = new NavigationPolygon();
  150. var offset = roomInfo.GetOffsetPosition();
  151. for (var i = 0; i < polygonArray.Length; i++)
  152. {
  153. var navigationPolygonData = polygonArray[i];
  154. var polygonPointArray = navigationPolygonData.ConvertPointsToVector2Array();
  155. //这里的位置需要加上房间位置
  156. for (var j = 0; j < polygonPointArray.Length; j++)
  157. {
  158. polygonPointArray[j] = polygonPointArray[j] + roomInfo.GetWorldPosition() - offset;
  159. }
  160. polygon.AddOutline(polygonPointArray);
  161. var points = new List<SerializeVector2>();
  162. for (var j = 0; j < polygonPointArray.Length; j++)
  163. {
  164. points.Add(new SerializeVector2(polygonPointArray[j]));
  165. }
  166. //存入汇总列表
  167. _roomStaticNavigationList.Add(new NavigationPolygonData(navigationPolygonData.Type, points));
  168. }
  169. polygon.MakePolygonsFromOutlines();
  170. var navigationPolygon = new NavigationRegion2D();
  171. navigationPolygon.Name = "NavigationRegion" + (GetChildCount() + 1);
  172. navigationPolygon.NavigationPolygon = polygon;
  173. AddChild(navigationPolygon);
  174. }
  175.  
  176. //创建门
  177. private void CreateDoor(RoomInfo roomInfo)
  178. {
  179. foreach (var doorInfo in roomInfo.Doors)
  180. {
  181. var door = ActivityObject.Create<RoomDoor>(ActivityIdPrefix.Other + "0001");
  182. doorInfo.Door = door;
  183. Vector2 offset;
  184. switch (doorInfo.Direction)
  185. {
  186. case DoorDirection.E:
  187. offset = new Vector2(-0.5f, 2);
  188. break;
  189. case DoorDirection.W:
  190. offset = new Vector2(0.5f, 2);
  191. break;
  192. case DoorDirection.S:
  193. offset = new Vector2(2f, -0.5f);
  194. break;
  195. case DoorDirection.N:
  196. offset = new Vector2(2f, 0.5f);
  197. break;
  198. default: offset = new Vector2();
  199. break;
  200. }
  201. door.Position = (doorInfo.OriginPosition + offset) * GameConfig.TileCellSize;
  202. door.Init(doorInfo);
  203. door.PutDown(RoomLayerEnum.NormalLayer, false);
  204. }
  205. }
  206.  
  207. //创建房间归属区域
  208. private void CreateRoomAisleAffiliation(RoomInfo roomInfo)
  209. {
  210. var affiliation = new AffiliationArea();
  211. affiliation.Name = "AffiliationArea" + (_affiliationIndex++);
  212. affiliation.Init(roomInfo, new Rect2(
  213. roomInfo.GetWorldPosition() + new Vector2(GameConfig.TileCellSize, GameConfig.TileCellSize),
  214. (roomInfo.Size - new Vector2I(2, 2)) * GameConfig.TileCellSize));
  215. roomInfo.Affiliation = affiliation;
  216. TileRoot.AddChild(affiliation);
  217. }
  218.  
  219. /// <summary>
  220. /// 玩家第一次进入某个房间回调
  221. /// </summary>
  222. private void OnPlayerFirstEnterRoom(object o)
  223. {
  224. var room = (RoomInfo)o;
  225. room.BeReady();
  226. }
  227.  
  228. /// <summary>
  229. /// 玩家进入某个房间回调
  230. /// </summary>
  231. private void OnPlayerEnterRoom(object o)
  232. {
  233. }
  234. /// <summary>
  235. /// 敌人死亡回调
  236. /// </summary>
  237. private void OnEnemyDie(object o)
  238. {
  239. var inst = (ActivityObject)o;
  240. var count = ActiveAffiliation.FindIncludeItemsCount(
  241. activityObject => activityObject != inst && activityObject.CollisionWithLayer(PhysicsLayer.Enemy)
  242. );
  243. if (count == 0)
  244. {
  245. ActiveRoom.OnClearRoom();
  246. }
  247. }
  248.  
  249. //绘制房间区域, debug 用
  250. private void DrawRoomInfo(RoomInfo room)
  251. {
  252. var cellSize = TileRoot.CellQuadrantSize;
  253. var pos1 = (room.Position + room.Size / 2) * cellSize;
  254. //绘制下一个房间
  255. foreach (var nextRoom in room.Next)
  256. {
  257. var pos2 = (nextRoom.Position + nextRoom.Size / 2) * cellSize;
  258. DrawLine(pos1, pos2, Colors.Red);
  259. DrawRoomInfo(nextRoom);
  260. }
  261.  
  262. DrawString(_font, pos1, room.Id.ToString());
  263.  
  264. //绘制门
  265. foreach (var roomDoor in room.Doors)
  266. {
  267. var originPos = roomDoor.OriginPosition * cellSize;
  268. switch (roomDoor.Direction)
  269. {
  270. case DoorDirection.E:
  271. DrawLine(originPos, originPos + new Vector2(3, 0) * cellSize, Colors.Yellow);
  272. DrawLine(originPos + new Vector2(0, 4) * cellSize, originPos + new Vector2(3, 4) * cellSize,
  273. Colors.Yellow);
  274. break;
  275. case DoorDirection.W:
  276. DrawLine(originPos, originPos - new Vector2(3, 0) * cellSize, Colors.Yellow);
  277. DrawLine(originPos + new Vector2(0, 4) * cellSize, originPos - new Vector2(3, -4) * cellSize,
  278. Colors.Yellow);
  279. break;
  280. case DoorDirection.S:
  281. DrawLine(originPos, originPos + new Vector2(0, 3) * cellSize, Colors.Yellow);
  282. DrawLine(originPos + new Vector2(4, 0) * cellSize, originPos + new Vector2(4, 3) * cellSize,
  283. Colors.Yellow);
  284. break;
  285. case DoorDirection.N:
  286. DrawLine(originPos, originPos - new Vector2(0, 3) * cellSize, Colors.Yellow);
  287. DrawLine(originPos + new Vector2(4, 0) * cellSize, originPos - new Vector2(-4, 3) * cellSize,
  288. Colors.Yellow);
  289. break;
  290. }
  291. //绘制房间区域
  292. DrawRect(new Rect2(room.Position * cellSize, room.Size * cellSize), Colors.Blue, false);
  293.  
  294. if (roomDoor.HasCross && roomDoor.RoomInfo.Id < roomDoor.ConnectRoom.Id)
  295. {
  296. DrawRect(new Rect2(roomDoor.Cross * cellSize, new Vector2(cellSize * 4, cellSize * 4)), Colors.Yellow, false);
  297. }
  298. }
  299. }
  300. }