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.Text.Json;
  6. using Config;
  7. using Godot;
  8.  
  9. public partial class GameApplication : Node2D
  10. {
  11. public static GameApplication Instance { get; private set; }
  12. /// <summary>
  13. /// 游戏渲染视口
  14. /// </summary>
  15. [Export] public SubViewport SubViewport;
  16.  
  17. /// <summary>
  18. /// SubViewportContainer 组件
  19. /// </summary>
  20. [Export] public SubViewportContainer SubViewportContainer;
  21.  
  22. /// <summary>
  23. /// 场景根节点
  24. /// </summary>
  25. [Export] public Node2D SceneRoot;
  26. /// <summary>
  27. /// 全局根节点
  28. /// </summary>
  29. [Export] public Node2D GlobalNodeRoot;
  30.  
  31. /// <summary>
  32. /// 是否开启调试
  33. /// </summary>
  34. [ExportGroup("Debug")]
  35. [Export] public bool Debug = false;
  36.  
  37. /// <summary>
  38. /// 测试用, 指定生成的房间
  39. /// </summary>
  40. [Export]
  41. public PackedScene[] DesignatedRoom;
  42.  
  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.  
  84. //初始化配置表
  85. ExcelConfig.Init();
  86. //初始化房间配置数据
  87. InitRoomConfig();
  88. //初始化 ActivityObject
  89. ActivityObject.InitActivity();
  90. //初始化武器数据
  91. Weapon.InitWeaponAttribute();
  92. DungeonConfig = new DungeonConfig();
  93. DungeonConfig.GroupName = "testGroup";
  94. DungeonConfig.RoomCount = 20;
  95. }
  96. public override void _EnterTree()
  97. {
  98. //随机化种子
  99. //GD.Randomize();
  100. //固定帧率
  101. Engine.MaxFps = 60;
  102. //调试绘制开关
  103. ActivityObject.IsDebug = Debug;
  104. //Engine.TimeScale = 0.2f;
  105.  
  106. ImageCanvas.Init(GetTree().CurrentScene);
  107. //窗体大小改变
  108. GetWindow().SizeChanged += OnWindowSizeChanged;
  109. RefreshSubViewportSize();
  110.  
  111. #if TOOLS
  112. InitDesignatedRoom();
  113. #endif
  114. //初始化ui
  115. UiManager.Init();
  116. // 初始化鼠标
  117. InitCursor();
  118. //地牢管理器
  119. DungeonManager = new DungeonManager();
  120. DungeonManager.Name = "DungeonManager";
  121. SceneRoot.AddChild(DungeonManager);
  122. //打开主菜单Ui
  123. UiManager.Open_Main();
  124. }
  125.  
  126. public override void _Process(double delta)
  127. {
  128. var newDelta = (float)delta;
  129. InputManager.Update(newDelta);
  130. //协程更新
  131. if (_coroutineList != null)
  132. {
  133. ProxyCoroutineHandler.ProxyUpdateCoroutine(ref _coroutineList, newDelta);
  134. }
  135. }
  136.  
  137. /// <summary>
  138. /// 创建新的 World 对象, 相当于清理房间
  139. /// </summary>
  140. public World CreateNewWorld()
  141. {
  142. if (World != null)
  143. {
  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. if (World != null)
  157. {
  158. World.QueueFree();
  159. }
  160.  
  161. World = null;
  162. }
  163. /// <summary>
  164. /// 将 viewport 以外的全局坐标 转换成 viewport 内的全局坐标
  165. /// </summary>
  166. public Vector2 GlobalToViewPosition(Vector2 globalPos)
  167. {
  168. //return globalPos;
  169. return globalPos / PixelScale - (ViewportSize / 2) + GameCamera.Main.GlobalPosition;
  170. }
  171.  
  172. /// <summary>
  173. /// 将 viewport 以内的全局坐标 转换成 viewport 外的全局坐标
  174. /// </summary>
  175. public Vector2 ViewToGlobalPosition(Vector2 viewPos)
  176. {
  177. // 3.5写法
  178. //return (viewPos - GameCamera.Main.GlobalPosition + (GameConfig.ViewportSize / 2)) * GameConfig.WindowScale - GameCamera.Main.SubPixelPosition;
  179. return (viewPos - (GameCamera.Main.GlobalPosition + GameCamera.Main.Offset) + (ViewportSize / 2)) * PixelScale;
  180. }
  181. /// <summary>
  182. /// 开启一个协程, 返回协程 id, 协程是在普通帧执行的, 支持: 协程嵌套, WaitForSeconds, WaitForFixedProcess, Task, SignalAwaiter
  183. /// </summary>
  184. public long StartCoroutine(IEnumerator able)
  185. {
  186. return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able);
  187. }
  188.  
  189. /// <summary>
  190. /// 根据协程 id 停止协程
  191. /// </summary>
  192. public void StopCoroutine(long coroutineId)
  193. {
  194. ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
  195. }
  196. /// <summary>
  197. /// 停止所有协程
  198. /// </summary>
  199. public void StopAllCoroutine()
  200. {
  201. ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
  202. }
  203.  
  204. //初始化房间配置
  205. private void InitRoomConfig()
  206. {
  207. //加载房间配置信息
  208. var file = FileAccess.Open(ResourcePath.resource_map_RoomConfig_json, FileAccess.ModeFlags.Read);
  209. var asText = file.GetAsText();
  210. RoomConfig = JsonSerializer.Deserialize<Dictionary<string, DungeonRoomGroup>>(asText);
  211. file.Dispose();
  212.  
  213. //初始化RoomConfigMap
  214. RoomConfigMap = new Dictionary<string, DungeonRoomSplit>();
  215. foreach (var dungeonRoomGroup in RoomConfig)
  216. {
  217. foreach (var dungeonRoomType in Enum.GetValues<DungeonRoomType>())
  218. {
  219. foreach (var dungeonRoomSplit in dungeonRoomGroup.Value.GetRoomList(dungeonRoomType))
  220. {
  221. RoomConfigMap.Add(dungeonRoomSplit.ScenePath, dungeonRoomSplit);
  222. }
  223. }
  224. }
  225. }
  226.  
  227. //窗体大小改变
  228. private void OnWindowSizeChanged()
  229. {
  230. var size = GetWindow().Size;
  231. ViewportSize = size / PixelScale;
  232. RefreshSubViewportSize();
  233. }
  234. //刷新视窗大小
  235. private void RefreshSubViewportSize()
  236. {
  237. var s = new Vector2I((int)ViewportSize.X, (int)ViewportSize.Y);
  238. s.X = s.X / 2 * 2;
  239. s.Y = s.Y / 2 * 2;
  240. SubViewport.Size = s;
  241. SubViewportContainer.Scale = new Vector2(PixelScale, PixelScale);
  242. SubViewportContainer.Size = s;
  243. }
  244.  
  245. //初始化鼠标
  246. private void InitCursor()
  247. {
  248. Input.MouseMode = Input.MouseModeEnum.Hidden;
  249. Cursor = ResourceManager.LoadAndInstantiate<Cursor>(ResourcePath.prefab_Cursor_tscn);
  250. var cursorLayer = new CanvasLayer();
  251. cursorLayer.Name = "CursorLayer";
  252. cursorLayer.Layer = UiManager.GetUiLayer(UiLayer.Pop).Layer + 10;
  253. AddChild(cursorLayer);
  254. cursorLayer.AddChild(Cursor);
  255. }
  256.  
  257. #if TOOLS
  258. //调试模式下, 指定生成哪些房间
  259. private void InitDesignatedRoom()
  260. {
  261. if (DesignatedRoom != null && DesignatedRoom.Length > 0)
  262. {
  263. var list = new List<DungeonRoomSplit>();
  264. foreach (var packedScene in DesignatedRoom)
  265. {
  266. if (RoomConfigMap.TryGetValue(packedScene.ResourcePath, out var dungeonRoomSplit))
  267. {
  268. list.Add(dungeonRoomSplit);
  269. }
  270. }
  271. DungeonGenerator.SetDesignatedRoom(list);
  272. }
  273. }
  274. #endif
  275.  
  276. }