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