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