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