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