Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / GameApplication.cs
  1.  
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text.Json;
  7. using Config;
  8. using Godot;
  9. using UI.BottomTips;
  10.  
  11. public partial class GameApplication : Node2D, ICoroutine
  12. {
  13. public static GameApplication Instance { get; private set; }
  14. /// <summary>
  15. /// 游戏渲染视口
  16. /// </summary>
  17. [Export] public SubViewport SubViewport;
  18.  
  19. /// <summary>
  20. /// SubViewportContainer 组件
  21. /// </summary>
  22. [Export] public SubViewportContainer SubViewportContainer;
  23.  
  24. /// <summary>
  25. /// 场景根节点
  26. /// </summary>
  27. [Export] public Node2D SceneRoot;
  28. /// <summary>
  29. /// 全局根节点
  30. /// </summary>
  31. [Export] public Node2D GlobalNodeRoot;
  32. /// <summary>
  33. /// 游戏目标帧率
  34. /// </summary>
  35. public int TargetFps { get; private set; }
  36. /// <summary>
  37. /// 鼠标指针
  38. /// </summary>
  39. public Cursor Cursor { get; private set; }
  40.  
  41. /// <summary>
  42. /// 游戏世界
  43. /// </summary>
  44. public World World { get; private set; }
  45.  
  46. /// <summary>
  47. /// 地牢管理器
  48. /// </summary>
  49. public DungeonManager DungeonManager { get; private set; }
  50. /// <summary>
  51. /// 房间配置
  52. /// </summary>
  53. public Dictionary<string, DungeonRoomGroup> RoomConfig { get; private set; }
  54. // /// <summary>
  55. // /// 房间配置数据, key: 模板房间资源路径
  56. // /// </summary>
  57. // public Dictionary<string, DungeonRoomSplit> RoomConfigMap { get; private set; }
  58.  
  59. /// <summary>
  60. /// 游戏视图大小
  61. /// </summary>
  62. public Vector2 ViewportSize { get; private set; } = new Vector2(480, 270);
  63. /// <summary>
  64. /// 像素缩放
  65. /// </summary>
  66. public int PixelScale { get; private set; } = 4;
  67. /// <summary>
  68. /// 地牢配置信息
  69. /// </summary>
  70. public DungeonConfig DungeonConfig { get; private set; }
  71.  
  72. //开启的协程
  73. private List<CoroutineData> _coroutineList;
  74. public GameApplication()
  75. {
  76. Instance = this;
  77. TargetFps = (int)DisplayServer.ScreenGetRefreshRate();
  78.  
  79. //初始化配置表
  80. ExcelConfig.Init();
  81. //初始化房间配置数据
  82. InitRoomConfig();
  83. //初始化武器数据
  84. Weapon.InitWeaponAttribute();
  85. DungeonConfig = new DungeonConfig();
  86. DungeonConfig.GroupName = RoomConfig.FirstOrDefault().Key;
  87. DungeonConfig.RoomCount = 20;
  88. }
  89. public override void _EnterTree()
  90. {
  91. //背景颜色
  92. RenderingServer.SetDefaultClearColor(new Color(0, 0, 0, 1));
  93. //随机化种子
  94. //GD.Randomize();
  95. //固定帧率
  96. Engine.MaxFps = TargetFps;
  97. //调试绘制开关
  98. ActivityObject.IsDebug = false;
  99. //Engine.TimeScale = 0.2f;
  100. //调整窗口分辨率
  101. OnWindowSizeChanged();
  102. //窗体大小改变
  103. GetWindow().SizeChanged += OnWindowSizeChanged;
  104.  
  105. ImageCanvas.Init(GetTree().CurrentScene);
  106. //初始化ui
  107. UiManager.Init();
  108. //调试Ui
  109. UiManager.Open_Debugger();
  110. // 初始化鼠标
  111. InitCursor();
  112. //地牢管理器
  113. DungeonManager = new DungeonManager();
  114. DungeonManager.Name = "DungeonManager";
  115. SceneRoot.AddChild(DungeonManager);
  116.  
  117. MapProjectManager.Init();
  118. BottomTipsPanel.Init();
  119. //打开主菜单Ui
  120. UiManager.Open_Main();
  121. //UiManager.Open_MapEditorProject();
  122. }
  123.  
  124. public override void _Process(double delta)
  125. {
  126. var newDelta = (float)delta;
  127. InputManager.Update(newDelta);
  128. SoundManager.Update(newDelta);
  129. //协程更新
  130. ProxyCoroutineHandler.ProxyUpdateCoroutine(ref _coroutineList, newDelta);
  131. }
  132.  
  133. /// <summary>
  134. /// 创建新的 World 对象, 相当于清理房间
  135. /// </summary>
  136. public World CreateNewWorld()
  137. {
  138. if (World != null)
  139. {
  140. ClearWorld();
  141. World.QueueFree();
  142. }
  143. World = ResourceManager.LoadAndInstantiate<World>(ResourcePath.scene_World_tscn);
  144. SceneRoot.AddChild(World);
  145. return World;
  146. }
  147.  
  148. /// <summary>
  149. /// 销毁 World 对象, 相当于清理房间
  150. /// </summary>
  151. public void DestroyWorld()
  152. {
  153. //销毁所有物体
  154. if (World != null)
  155. {
  156. ClearWorld();
  157. World.QueueFree();
  158. }
  159. //销毁池中所有物体
  160. ObjectPool.DisposeAllItem();
  161.  
  162. World = null;
  163. }
  164. /// <summary>
  165. /// 将 viewport 以外的全局坐标 转换成 viewport 内的全局坐标
  166. /// </summary>
  167. public Vector2 GlobalToViewPosition(Vector2 globalPos)
  168. {
  169. return globalPos / PixelScale - (ViewportSize / 2) + GameCamera.Main.GlobalPosition - GameCamera.Main.PixelOffset;
  170. }
  171.  
  172. /// <summary>
  173. /// 将 viewport 以内的全局坐标 转换成 viewport 外的全局坐标
  174. /// </summary>
  175. public Vector2 ViewToGlobalPosition(Vector2 viewPos)
  176. {
  177. return (viewPos + GameCamera.Main.PixelOffset - (GameCamera.Main.GlobalPosition + GameCamera.Main.Offset) + (ViewportSize / 2)) * PixelScale;
  178. }
  179. public long StartCoroutine(IEnumerator able)
  180. {
  181. return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able);
  182. }
  183. public void StopCoroutine(long coroutineId)
  184. {
  185. ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
  186. }
  187.  
  188. public bool IsCoroutineOver(long coroutineId)
  189. {
  190. return ProxyCoroutineHandler.ProxyIsCoroutineOver(ref _coroutineList, coroutineId);
  191. }
  192.  
  193. public void StopAllCoroutine()
  194. {
  195. ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
  196. }
  197.  
  198. public void SetRoomConfig(Dictionary<string,DungeonRoomGroup> roomConfig)
  199. {
  200. RoomConfig = roomConfig;
  201. InitReadyRoom();
  202. }
  203.  
  204. //初始化房间配置
  205. private void InitRoomConfig()
  206. {
  207. //加载房间配置信息
  208. var asText = ResourceManager.LoadText("res://" + GameConfig.RoomTileDir + GameConfig.RoomGroupConfigFile);
  209. RoomConfig = JsonSerializer.Deserialize<Dictionary<string, DungeonRoomGroup>>(asText);
  210.  
  211. InitReadyRoom();
  212. }
  213. //初始化房间数据
  214. private void InitReadyRoom()
  215. {
  216. foreach (var dungeonRoomGroup in RoomConfig)
  217. {
  218. RemoveUnreadyRooms(dungeonRoomGroup.Value.BattleList);
  219. RemoveUnreadyRooms(dungeonRoomGroup.Value.InletList);
  220. RemoveUnreadyRooms(dungeonRoomGroup.Value.OutletList);
  221. RemoveUnreadyRooms(dungeonRoomGroup.Value.BossList);
  222. RemoveUnreadyRooms(dungeonRoomGroup.Value.ShopList);
  223. RemoveUnreadyRooms(dungeonRoomGroup.Value.RewardList);
  224. RemoveUnreadyRooms(dungeonRoomGroup.Value.EventList);
  225. }
  226. }
  227. //移除未准备好的房间
  228. private void RemoveUnreadyRooms(List<DungeonRoomSplit> roomInfos)
  229. {
  230. for (var i = 0; i < roomInfos.Count; i++)
  231. {
  232. if (roomInfos[i].ErrorType != RoomErrorType.None) //存在错误
  233. {
  234. roomInfos.RemoveAt(i);
  235. i--;
  236. }
  237. }
  238. }
  239.  
  240. //窗体大小改变
  241. private void OnWindowSizeChanged()
  242. {
  243. var size = GetWindow().Size;
  244. ViewportSize = size / PixelScale;
  245. RefreshSubViewportSize();
  246. }
  247. //刷新视窗大小
  248. private void RefreshSubViewportSize()
  249. {
  250. var s = new Vector2I((int)ViewportSize.X, (int)ViewportSize.Y);
  251. s.X = s.X / 2 * 2 + 2;
  252. s.Y = s.Y / 2 * 2 + 2;
  253. SubViewport.Size = s;
  254. SubViewportContainer.Scale = new Vector2(PixelScale, PixelScale);
  255. SubViewportContainer.Size = s;
  256. SubViewportContainer.Position = new Vector2(-PixelScale, -PixelScale);
  257. }
  258.  
  259. //初始化鼠标
  260. private void InitCursor()
  261. {
  262. Cursor = ResourceManager.LoadAndInstantiate<Cursor>(ResourcePath.prefab_Cursor_tscn);
  263. var cursorLayer = new CanvasLayer();
  264. cursorLayer.Name = "CursorLayer";
  265. cursorLayer.Layer = UiManager.GetUiLayer(UiLayer.Pop).Layer + 10;
  266. AddChild(cursorLayer);
  267. cursorLayer.AddChild(Cursor);
  268. }
  269.  
  270. //清理世界
  271. private void ClearWorld()
  272. {
  273. var childCount = World.NormalLayer.GetChildCount();
  274. for (var i = 0; i < childCount; i++)
  275. {
  276. var c = World.NormalLayer.GetChild(i);
  277. if (c is IDestroy destroy)
  278. {
  279. destroy.Destroy();
  280. }
  281. }
  282. childCount = World.YSortLayer.GetChildCount();
  283. for (var i = 0; i < childCount; i++)
  284. {
  285. var c = World.YSortLayer.GetChild(i);
  286. if (c is IDestroy destroy)
  287. {
  288. destroy.Destroy();
  289. }
  290. }
  291. }
  292. }