Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / roomMap / RoomMapPanel.cs
@小李xl 小李xl on 28 Feb 2024 13 KB 大厅制作中
  1. using System.Collections.Generic;
  2. using Godot;
  3. using UI.RoomUI;
  4.  
  5. namespace UI.RoomMap;
  6.  
  7. /// <summary>
  8. /// 房间的小地图
  9. /// </summary>
  10. public partial class RoomMapPanel : RoomMap
  11. {
  12. private EventFactory _factory = EventManager.CreateEventFactory();
  13. //需要刷新的问号的房间队列
  14. private List<RoomDoorInfo> _needRefresh = new List<RoomDoorInfo>();
  15. //正在使用的敌人标记列表
  16. private List<Sprite2D> _enemySpriteList = new List<Sprite2D>();
  17. //已经回收的敌人标记
  18. private Stack<Sprite2D> _spriteStack = new Stack<Sprite2D>();
  19. //是否放大地图
  20. private bool _isMagnifyMap = false;
  21.  
  22. private UiEventBinder _dragBinder;
  23. //放大地图后拖拽的偏移
  24. private Vector2 _mapOffset;
  25. //放大地图后鼠标悬停的房间
  26. private RoomInfo _mouseHoverRoom;
  27. private Color _originOutlineColor;
  28. //是否展开地图
  29. private bool _pressMapFlag = false;
  30. private Tween _transmissionTween;
  31. public override void OnCreateUi()
  32. {
  33. _ = S_Mark;
  34. S_Bg.Instance.Visible = false;
  35. S_MagnifyMapBar.Instance.Visible = false;
  36. InitMap();
  37. _factory.AddEventListener(EventEnum.OnPlayerFirstEnterRoom, OnPlayerFirstEnterRoom);
  38. _factory.AddEventListener(EventEnum.OnPlayerFirstEnterAisle, OnPlayerFirstEnterAisle);
  39.  
  40. S_DrawContainer.Instance.Resized += OnDrawContainerResized;
  41. }
  42.  
  43. public override void OnDestroyUi()
  44. {
  45. _factory.RemoveAllEventListener();
  46.  
  47. if (_transmissionTween != null)
  48. {
  49. _transmissionTween.Dispose();
  50. }
  51. }
  52.  
  53. public override void Process(float delta)
  54. {
  55. if (_transmissionTween == null) //不在传送过程中
  56. {
  57. if (!InputManager.Map)
  58. {
  59. _pressMapFlag = false;
  60. }
  61. //按下地图按键
  62. if (InputManager.Map && !_isMagnifyMap && !_pressMapFlag) //展开小地图
  63. {
  64. if (UiManager.GetUiInstanceCount(UiManager.UiNames.PauseMenu) == 0)
  65. {
  66. World.Current.Pause = true;
  67. _pressMapFlag = true;
  68. _isMagnifyMap = true;
  69. MagnifyMap();
  70. }
  71. }
  72. else if (!InputManager.Map && _isMagnifyMap) //还原小地图
  73. {
  74. ResetMap();
  75. _isMagnifyMap = false;
  76. World.Current.Pause = false;
  77. }
  78. }
  79. //更新敌人位置
  80. {
  81. var enemyList = World.Current.Enemy_InstanceList;
  82. if (enemyList.Count == 0) //没有敌人
  83. {
  84. foreach (var sprite in _enemySpriteList)
  85. {
  86. S_Root.RemoveChild(sprite);
  87. _spriteStack.Push(sprite);
  88. }
  89. _enemySpriteList.Clear();
  90. }
  91. else //更新位置
  92. {
  93. var count = 0; //绘制数量
  94. for (var i = 0; i < enemyList.Count; i++)
  95. {
  96. var enemy = enemyList[i];
  97. if (!enemy.IsDestroyed && !enemy.IsDie && enemy.AffiliationArea != null && enemy.AffiliationArea.RoomInfo.RoomFogMask.IsExplored)
  98. {
  99. count++;
  100. Sprite2D sprite;
  101. if (i >= _enemySpriteList.Count)
  102. {
  103. if (_spriteStack.Count > 0)
  104. {
  105. sprite = _spriteStack.Pop();
  106. }
  107. else
  108. {
  109. sprite = new Sprite2D();
  110. sprite.Texture = ResourceManager.LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_Block_png);
  111. sprite.Modulate = new Color(1, 0, 0);
  112. }
  113. _enemySpriteList.Add(sprite);
  114. S_Root.AddChild(sprite);
  115. }
  116. else
  117. {
  118. sprite = _enemySpriteList[i];
  119. }
  120. //更新标记位置
  121. sprite.Position = enemy.GetCenterPosition() / 16;
  122. }
  123. }
  124. //回收多余的标记
  125. while (_enemySpriteList.Count > count)
  126. {
  127. var index = _enemySpriteList.Count - 1;
  128. var sprite = _enemySpriteList[index];
  129. S_Root.RemoveChild(sprite);
  130. _spriteStack.Push(sprite);
  131. _enemySpriteList.RemoveAt(index);
  132. }
  133. }
  134. }
  135. //更新预览图标
  136. if (_needRefresh.Count > 0)
  137. {
  138. foreach (var roomDoorInfo in _needRefresh)
  139. {
  140. HandlerRefreshUnknownSprite(roomDoorInfo);
  141. }
  142. _needRefresh.Clear();
  143. }
  144.  
  145. if (Player.Current != null)
  146. {
  147. //更新地图中心点位置
  148. var playPosition = Player.Current.GetCenterPosition();
  149. if (!_isMagnifyMap)
  150. {
  151. S_Root.Instance.Position = CalcRootPosition(playPosition);
  152. }
  153. else
  154. {
  155. S_Root.Instance.Position = CalcRootPosition(playPosition) + _mapOffset;
  156. S_Mark.Instance.Position = S_DrawContainer.Instance.Size / 2 + _mapOffset;
  157. }
  158.  
  159. var area = Player.Current.AffiliationArea;
  160. //传送
  161. if (_pressMapFlag && _mouseHoverRoom != null &&
  162. area != null && !area.RoomInfo.IsSeclusion &&
  163. Input.IsMouseButtonPressed(MouseButton.Right))
  164. {
  165. //执行传送操作
  166. DoTransmission((_mouseHoverRoom.Waypoints + new Vector2(0.5f, 0.5f)) * GameConfig.TileCellSize);
  167. ResetMap();
  168. _isMagnifyMap = false;
  169. World.Current.Pause = false;
  170. }
  171. }
  172. }
  173.  
  174. private void OnDrawContainerResized()
  175. {
  176. S_Mark.Instance.Position = S_DrawContainer.Instance.Size / 2;
  177. }
  178.  
  179. //放大小地图
  180. private void MagnifyMap()
  181. {
  182. GameApplication.Instance.Cursor.SetGuiMode(true);
  183. S_DrawContainer.Reparent(S_MagnifyMapBar);
  184. S_DrawContainer.Instance.Position = new Vector2(1, 1);
  185. S_Bg.Instance.Visible = true;
  186. S_MagnifyMapBar.Instance.Visible = true;
  187. S_MapBar.Instance.Visible = false;
  188. _mapOffset = Vector2.Zero;
  189.  
  190. _dragBinder = S_DrawContainer.Instance.AddDragListener((state, delta) =>
  191. {
  192. if (state == DragState.DragMove)
  193. {
  194. _mapOffset += delta;
  195. }
  196. });
  197. }
  198.  
  199. //还原小地图
  200. private void ResetMap()
  201. {
  202. GameApplication.Instance.Cursor.SetGuiMode(false);
  203. S_DrawContainer.Reparent(S_MapBar);
  204. S_DrawContainer.Instance.Position = new Vector2(1, 1);
  205. S_Bg.Instance.Visible = false;
  206. S_MagnifyMapBar.Instance.Visible = false;
  207. S_MapBar.Instance.Visible = true;
  208. ResetOutlineColor();
  209.  
  210. if (_dragBinder != null)
  211. {
  212. _dragBinder.UnBind();
  213. _dragBinder = null;
  214. }
  215. }
  216.  
  217. private void ResetOutlineColor()
  218. {
  219. if (_mouseHoverRoom != null)
  220. {
  221. ((ShaderMaterial)_mouseHoverRoom.PreviewSprite.Material).SetShaderParameter("outline_color", _originOutlineColor);
  222. _mouseHoverRoom = null;
  223. }
  224. }
  225. //初始化小地图
  226. private void InitMap()
  227. {
  228. var startRoom = GameApplication.Instance.DungeonManager.StartRoomInfo;
  229. if (startRoom == null)
  230. {
  231. HideUi();
  232. return;
  233. }
  234. startRoom.EachRoom(roomInfo =>
  235. {
  236. //房间
  237. roomInfo.PreviewSprite.Visible = false;
  238. S_Root.AddChild(roomInfo.PreviewSprite);
  239.  
  240. roomInfo.PreviewSprite.MouseEntered += () =>
  241. {
  242. if (!_pressMapFlag)
  243. {
  244. return;
  245. }
  246. ResetOutlineColor();
  247. _mouseHoverRoom = roomInfo;
  248. var shaderMaterial = (ShaderMaterial)roomInfo.PreviewSprite.Material;
  249. _originOutlineColor = shaderMaterial.GetShaderParameter("outline_color").AsColor();
  250. //玩家所在的房间门是否打开
  251. var area = Player.Current.AffiliationArea;
  252. if (area != null)
  253. {
  254. var isOpen = !area.RoomInfo.IsSeclusion;
  255. if (isOpen)
  256. {
  257. shaderMaterial.SetShaderParameter("outline_color", new Color(0, 1, 0, 0.9f));
  258. }
  259. else
  260. {
  261. shaderMaterial.SetShaderParameter("outline_color", new Color(1, 0, 0, 0.9f));
  262. }
  263. }
  264. };
  265. roomInfo.PreviewSprite.MouseExited += () =>
  266. {
  267. if (!_pressMapFlag)
  268. {
  269. return;
  270. }
  271. ResetOutlineColor();
  272. };
  273. //过道
  274. if (roomInfo.Doors != null)
  275. {
  276. foreach (var roomInfoDoor in roomInfo.Doors)
  277. {
  278. if (roomInfoDoor.IsForward)
  279. {
  280. roomInfoDoor.AislePreviewSprite.Visible = false;
  281. S_Root.AddChild(roomInfoDoor.AislePreviewSprite);
  282. }
  283. }
  284. }
  285. });
  286. }
  287. private void OnPlayerFirstEnterRoom(object data)
  288. {
  289. var roomInfo = (RoomInfo)data;
  290. if (roomInfo.PreviewSprite != null)
  291. {
  292. roomInfo.PreviewSprite.Visible = true;
  293. }
  294.  
  295. if (roomInfo.Doors!= null)
  296. {
  297. foreach (var roomDoor in roomInfo.Doors)
  298. {
  299. RefreshUnknownSprite(roomDoor);
  300. }
  301. }
  302. }
  303. private void OnPlayerFirstEnterAisle(object data)
  304. {
  305. var roomDoorInfo = (RoomDoorInfo)data;
  306. roomDoorInfo.AislePreviewSprite.Visible = true;
  307.  
  308. RefreshUnknownSprite(roomDoorInfo);
  309. RefreshUnknownSprite(roomDoorInfo.ConnectDoor);
  310. }
  311.  
  312. //进入刷新问号队列
  313. private void RefreshUnknownSprite(RoomDoorInfo roomDoorInfo)
  314. {
  315. if (!_needRefresh.Contains(roomDoorInfo))
  316. {
  317. _needRefresh.Add(roomDoorInfo);
  318. }
  319. }
  320.  
  321. //刷新问号
  322. private void HandlerRefreshUnknownSprite(RoomDoorInfo roomDoorInfo)
  323. {
  324. //是否探索房间
  325. var flag1 = roomDoorInfo.RoomInfo.RoomFogMask.IsExplored;
  326. //是否探索过道
  327. var flag2 = roomDoorInfo.AisleFogMask.IsExplored;
  328. if (flag1 == flag2) //不显示问号
  329. {
  330. if (roomDoorInfo.UnknownSprite != null)
  331. {
  332. roomDoorInfo.UnknownSprite.QueueFree();
  333. roomDoorInfo.UnknownSprite = null;
  334. }
  335. }
  336. else
  337. {
  338. var unknownSprite = roomDoorInfo.UnknownSprite ?? CreateUnknownSprite(roomDoorInfo);
  339. var pos = (roomDoorInfo.OriginPosition + roomDoorInfo.GetEndPosition()) / 2;
  340. if (!flag2) //偏向过道
  341. {
  342. if (roomDoorInfo.Direction == DoorDirection.N)
  343. pos += new Vector2I(0, -1);
  344. else if (roomDoorInfo.Direction == DoorDirection.S)
  345. pos += new Vector2I(0, 3);
  346. else if (roomDoorInfo.Direction == DoorDirection.E)
  347. pos += new Vector2I(2, 1);
  348. else if (roomDoorInfo.Direction == DoorDirection.W)
  349. pos += new Vector2I(-2, 1);
  350. }
  351. else //偏向房间
  352. {
  353. if (roomDoorInfo.Direction == DoorDirection.N)
  354. pos -= new Vector2I(0, -4);
  355. else if (roomDoorInfo.Direction == DoorDirection.S)
  356. pos -= new Vector2I(0, 1);
  357. else if (roomDoorInfo.Direction == DoorDirection.E)
  358. pos -= new Vector2I(3, -1);
  359. else if (roomDoorInfo.Direction == DoorDirection.W)
  360. pos -= new Vector2I(-3, -1);
  361. }
  362. unknownSprite.Position = pos;
  363. }
  364. }
  365.  
  366. private Sprite2D CreateUnknownSprite(RoomDoorInfo roomInfoDoor)
  367. {
  368. var unknownSprite = new Sprite2D();
  369. unknownSprite.Texture = ResourceManager.LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_Unknown_png);
  370. unknownSprite.Scale = new Vector2(0.25f, 0.25f);
  371. roomInfoDoor.UnknownSprite = unknownSprite;
  372. S_Root.AddChild(unknownSprite);
  373. return unknownSprite;
  374. }
  375.  
  376. private Vector2 CalcRootPosition(Vector2 pos)
  377. {
  378. return S_DrawContainer.Instance.Size / 2 - pos / 16 * S_Root.Instance.Scale;
  379. }
  380. private void DoTransmission(Vector2 position)
  381. {
  382. var roomUI = (RoomUIPanel)ParentUi;
  383. roomUI.S_Mask.Instance.Visible = true;
  384. roomUI.S_Mask.Instance.Color = new Color(0, 0, 0, 0);
  385. _transmissionTween = CreateTween();
  386. _transmissionTween.TweenProperty(roomUI.S_Mask.Instance, "color", new Color(0, 0, 0), 0.3f);
  387. _transmissionTween.TweenCallback(Callable.From(() =>
  388. {
  389. Player.Current.Position = position;
  390. }));
  391. _transmissionTween.TweenInterval(0.2f);
  392. _transmissionTween.TweenProperty(roomUI.S_Mask.Instance, "color", new Color(0, 0, 0, 0), 0.3f);
  393. _transmissionTween.TweenCallback(Callable.From(() =>
  394. {
  395. _transmissionTween = null;
  396. }));
  397. _transmissionTween.Play();
  398. }
  399. }