Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / roomMap / RoomMapPanel.cs
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using Godot;
  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. public override void OnCreateUi()
  29. {
  30. _ = S_Mark;
  31. S_Bg.Instance.Visible = false;
  32. S_MagnifyMapBar.Instance.Visible = false;
  33. InitMap();
  34. _factory.AddEventListener(EventEnum.OnPlayerFirstEnterRoom, OnPlayerFirstEnterRoom);
  35. _factory.AddEventListener(EventEnum.OnPlayerFirstEnterAisle, OnPlayerFirstEnterAisle);
  36.  
  37. S_DrawContainer.Instance.Resized += OnDrawContainerResized;
  38. }
  39.  
  40.  
  41. public override void OnDestroyUi()
  42. {
  43. _factory.RemoveAllEventListener();
  44. if (_dragBinder != null)
  45. {
  46. _dragBinder.UnBind();
  47. }
  48. }
  49.  
  50. public override void Process(float delta)
  51. {
  52. //按下地图按键
  53. if (InputManager.Map && !_isMagnifyMap)
  54. {
  55. if (UiManager.GetUiInstanceCount(UiManager.UiName.PauseMenu) == 0)
  56. {
  57. World.Current.Pause = true;
  58. _isMagnifyMap = true;
  59. MagnifyMap();
  60. }
  61. }
  62. else if (!InputManager.Map && _isMagnifyMap)
  63. {
  64. ResetMap();
  65. _isMagnifyMap = false;
  66. World.Current.Pause = false;
  67. }
  68. //更新敌人位置
  69. if (World.Current != null)
  70. {
  71. var enemyList = World.Current.Enemy_InstanceList;
  72. if (enemyList.Count == 0) //没有敌人
  73. {
  74. foreach (var sprite in _enemySpriteList)
  75. {
  76. S_Root.RemoveChild(sprite);
  77. _spriteStack.Push(sprite);
  78. }
  79. _enemySpriteList.Clear();
  80. }
  81. else //更新位置
  82. {
  83. var count = 0; //绘制数量
  84. for (var i = 0; i < enemyList.Count; i++)
  85. {
  86. var enemy = enemyList[i];
  87. if (!enemy.IsDestroyed && !enemy.IsDie && enemy.AffiliationArea != null && enemy.AffiliationArea.RoomInfo.RoomFogMask.IsExplored)
  88. {
  89. count++;
  90. Sprite2D sprite;
  91. if (i >= _enemySpriteList.Count)
  92. {
  93. if (_spriteStack.Count > 0)
  94. {
  95. sprite = _spriteStack.Pop();
  96. }
  97. else
  98. {
  99. sprite = new Sprite2D();
  100. sprite.Texture = ResourceManager.LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_Block_png);
  101. sprite.Modulate = new Color(1, 0, 0);
  102. }
  103. _enemySpriteList.Add(sprite);
  104. S_Root.AddChild(sprite);
  105. }
  106. else
  107. {
  108. sprite = _enemySpriteList[i];
  109. }
  110. //更新标记位置
  111. sprite.Position = enemy.Position / 16;
  112. }
  113. }
  114. //回收多余的标记
  115. while (_enemySpriteList.Count > count)
  116. {
  117. var index = _enemySpriteList.Count - 1;
  118. var sprite = _enemySpriteList[index];
  119. S_Root.RemoveChild(sprite);
  120. _spriteStack.Push(sprite);
  121. _enemySpriteList.RemoveAt(index);
  122. }
  123. }
  124. }
  125. //更新预览图标
  126. if (_needRefresh.Count > 0)
  127. {
  128. foreach (var roomDoorInfo in _needRefresh)
  129. {
  130. HandlerRefreshUnknownSprite(roomDoorInfo);
  131. }
  132. _needRefresh.Clear();
  133. }
  134.  
  135. //更新地图中心点位置
  136. if (!_isMagnifyMap)
  137. {
  138. S_Root.Instance.Position = CalcRootPosition(Player.Current.Position);
  139. }
  140. else
  141. {
  142. S_Root.Instance.Position = CalcRootPosition(Player.Current.Position) + _mapOffset;
  143. S_Mark.Instance.Position = S_DrawContainer.Instance.Size / 2 + _mapOffset;
  144. }
  145. }
  146.  
  147. private void OnDrawContainerResized()
  148. {
  149. S_Mark.Instance.Position = S_DrawContainer.Instance.Size / 2;
  150. }
  151.  
  152. //放大小地图
  153. private void MagnifyMap()
  154. {
  155. GameApplication.Instance.Cursor.SetGuiMode(true);
  156. S_DrawContainer.Reparent(S_MagnifyMapBar);
  157. S_DrawContainer.Instance.Position = new Vector2(1, 1);
  158. S_Bg.Instance.Visible = true;
  159. S_MagnifyMapBar.Instance.Visible = true;
  160. S_MapBar.Instance.Visible = false;
  161. _mapOffset = Vector2.Zero;
  162. _dragBinder = DragUiManager.BindDrag(S_DrawContainer.Instance, (state, delta) =>
  163. {
  164. if (state == DragState.DragMove)
  165. {
  166. _mapOffset += delta;
  167. }
  168. });
  169. }
  170.  
  171. //还原小地图
  172. private void ResetMap()
  173. {
  174. GameApplication.Instance.Cursor.SetGuiMode(false);
  175. S_DrawContainer.Reparent(S_MapBar);
  176. S_DrawContainer.Instance.Position = new Vector2(1, 1);
  177. S_Bg.Instance.Visible = false;
  178. S_MagnifyMapBar.Instance.Visible = false;
  179. S_MapBar.Instance.Visible = true;
  180. ResetOutlineColor();
  181.  
  182. if (_dragBinder != null)
  183. {
  184. _dragBinder.UnBind();
  185. }
  186. }
  187.  
  188. private void ResetOutlineColor()
  189. {
  190. if (_mouseHoverRoom != null)
  191. {
  192. ((ShaderMaterial)_mouseHoverRoom.PreviewSprite.Material).SetShaderParameter("outline_color", _originOutlineColor);
  193. _mouseHoverRoom = null;
  194. }
  195. }
  196. //初始化小地图
  197. private void InitMap()
  198. {
  199. var startRoom = GameApplication.Instance.DungeonManager.StartRoomInfo;
  200. startRoom.EachRoom(roomInfo =>
  201. {
  202. //房间
  203. roomInfo.PreviewSprite.Visible = false;
  204. S_Root.AddChild(roomInfo.PreviewSprite);
  205.  
  206. roomInfo.PreviewSprite.MouseEntered += () =>
  207. {
  208. ResetOutlineColor();
  209. _mouseHoverRoom = roomInfo;
  210. var shaderMaterial = (ShaderMaterial)roomInfo.PreviewSprite.Material;
  211. _originOutlineColor = shaderMaterial.GetShaderParameter("outline_color").AsColor();
  212. shaderMaterial.SetShaderParameter("outline_color", new Color(0, 1, 0, 0.9f));
  213. };
  214. roomInfo.PreviewSprite.MouseExited += ResetOutlineColor;
  215. //过道
  216. if (roomInfo.Doors != null)
  217. {
  218. foreach (var roomInfoDoor in roomInfo.Doors)
  219. {
  220. if (roomInfoDoor.IsForward)
  221. {
  222. roomInfoDoor.AislePreviewSprite.Visible = false;
  223. S_Root.AddChild(roomInfoDoor.AislePreviewSprite);
  224. }
  225. }
  226. }
  227. });
  228. }
  229. private void OnPlayerFirstEnterRoom(object data)
  230. {
  231. var roomInfo = (RoomInfo)data;
  232. roomInfo.PreviewSprite.Visible = true;
  233. if (roomInfo.Doors!= null)
  234. {
  235. foreach (var roomDoor in roomInfo.Doors)
  236. {
  237. RefreshUnknownSprite(roomDoor);
  238. }
  239. }
  240. }
  241. private void OnPlayerFirstEnterAisle(object data)
  242. {
  243. var roomDoorInfo = (RoomDoorInfo)data;
  244. roomDoorInfo.AislePreviewSprite.Visible = true;
  245.  
  246. RefreshUnknownSprite(roomDoorInfo);
  247. RefreshUnknownSprite(roomDoorInfo.ConnectDoor);
  248. }
  249.  
  250. //进入刷新问号队列
  251. private void RefreshUnknownSprite(RoomDoorInfo roomDoorInfo)
  252. {
  253. if (!_needRefresh.Contains(roomDoorInfo))
  254. {
  255. _needRefresh.Add(roomDoorInfo);
  256. }
  257. }
  258.  
  259. //刷新问号
  260. private void HandlerRefreshUnknownSprite(RoomDoorInfo roomDoorInfo)
  261. {
  262. //是否探索房间
  263. var flag1 = roomDoorInfo.RoomInfo.RoomFogMask.IsExplored;
  264. //是否探索过道
  265. var flag2 = roomDoorInfo.AisleFogMask.IsExplored;
  266. if (flag1 == flag2) //不显示问号
  267. {
  268. if (roomDoorInfo.UnknownSprite != null)
  269. {
  270. roomDoorInfo.UnknownSprite.QueueFree();
  271. roomDoorInfo.UnknownSprite = null;
  272. }
  273. }
  274. else
  275. {
  276. var unknownSprite = roomDoorInfo.UnknownSprite ?? CreateUnknownSprite(roomDoorInfo);
  277. var pos = (roomDoorInfo.OriginPosition + roomDoorInfo.GetEndPosition()) / 2;
  278. if (!flag2) //偏向过道
  279. {
  280. if (roomDoorInfo.Direction == DoorDirection.N)
  281. pos += new Vector2I(0, -2);
  282. else if (roomDoorInfo.Direction == DoorDirection.S)
  283. pos += new Vector2I(0, 2);
  284. else if (roomDoorInfo.Direction == DoorDirection.E)
  285. pos += new Vector2I(2, 0);
  286. else if (roomDoorInfo.Direction == DoorDirection.W)
  287. pos += new Vector2I(-2, 0);
  288. }
  289. else //偏向房间
  290. {
  291. if (roomDoorInfo.Direction == DoorDirection.N)
  292. pos -= new Vector2I(0, -2);
  293. else if (roomDoorInfo.Direction == DoorDirection.S)
  294. pos -= new Vector2I(0, 2);
  295. else if (roomDoorInfo.Direction == DoorDirection.E)
  296. pos -= new Vector2I(2, 0);
  297. else if (roomDoorInfo.Direction == DoorDirection.W)
  298. pos -= new Vector2I(-2, 0);
  299. }
  300. unknownSprite.Position = pos;
  301. }
  302. }
  303.  
  304. private Sprite2D CreateUnknownSprite(RoomDoorInfo roomInfoDoor)
  305. {
  306. var unknownSprite = new Sprite2D();
  307. unknownSprite.Texture = ResourceManager.LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_Unknown_png);
  308. unknownSprite.Scale = new Vector2(0.25f, 0.25f);
  309. roomInfoDoor.UnknownSprite = unknownSprite;
  310. S_Root.AddChild(unknownSprite);
  311. return unknownSprite;
  312. }
  313.  
  314. private Vector2 CalcRootPosition(Vector2 pos)
  315. {
  316. return S_DrawContainer.Instance.Size / 2 - pos / 16 * S_Root.Instance.Scale;
  317. }
  318.  
  319. }