Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / GameApplication.cs
@小李xl 小李xl on 29 May 2023 6 KB 武器素材更改

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.Json;
using Godot;

public partial class GameApplication : Node2D
{
	public static GameApplication Instance { get; private set; }
	
	/// <summary>
	/// 游戏渲染视口
	/// </summary>
	[Export] public SubViewport SubViewport;

	/// <summary>
	/// SubViewportContainer 组件
	/// </summary>
	[Export] public SubViewportContainer SubViewportContainer;

	/// <summary>
	/// 场景根节点
	/// </summary>
	[Export] public Node2D SceneRoot;
	
	/// <summary>
	/// 全局根节点
	/// </summary>
	[Export] public Node2D GlobalNodeRoot;

	/// <summary>
	/// 是否开启调试
	/// </summary>
	[ExportGroup("Debug")]
	[Export] public bool Debug = false;

	/// <summary>
	/// 测试用, 指定生成的房间
	/// </summary>
	[Export]
	public PackedScene[] DesignatedRoom;

	/// <summary>
	/// 鼠标指针
	/// </summary>
	public Cursor Cursor { get; private set; }
	
	/// <summary>
	/// 游戏世界
	/// </summary>
	public World World { get; private set; }

	/// <summary>
	/// 地牢管理器
	/// </summary>
	public DungeonManager DungeonManager { get; private set; }
	
	/// <summary>
	/// 房间配置
	/// </summary>
	public Dictionary<string, DungeonRoomGroup> RoomConfig { get; private set; }
	
	/// <summary>
	/// 房间配置数据, key: 模板房间资源路径
	/// </summary>
	public Dictionary<string, DungeonRoomSplit> RoomConfigMap { get; private set; }

	/// <summary>
	/// 游戏视图大小
	/// </summary>
	public Vector2 ViewportSize { get; private set; } = new Vector2(480, 270);
	
	/// <summary>
	/// 像素缩放
	/// </summary>
	public int PixelScale { get; private set; } = 4;
	
	/// <summary>
	/// 地牢配置信息
	/// </summary>
	public DungeonConfig DungeonConfig { get; private set; }

	//开启的协程
	private List<CoroutineData> _coroutineList;
	
	public GameApplication()
	{
		Instance = this;
		
		InitRoomConfig();

		//初始化 ActivityObject
		ActivityObject.InitActivity();
		
		DungeonConfig = new DungeonConfig();
		DungeonConfig.GroupName = "testGroup";
		DungeonConfig.RoomCount = 20;
	}
	
	public override void _EnterTree()
	{
		//随机化种子
		//GD.Randomize();
		//固定帧率
		Engine.MaxFps = 60;
		//调试绘制开关
		ActivityObject.IsDebug = Debug;
		//Engine.TimeScale = 0.2f;

		//窗体大小改变
		GetWindow().SizeChanged += OnWindowSizeChanged;
		RefreshSubViewportSize();

#if TOOLS
		InitDesignatedRoom();
#endif
		//初始化ui
		UiManager.Init();
		// 初始化鼠标
		InitCursor();
		//地牢管理器
		DungeonManager = new DungeonManager();
		DungeonManager.Name = "DungeonManager";
		SceneRoot.AddChild(DungeonManager);
		//打开主菜单Ui
		UiManager.Open_Main();
	}

	public override void _Process(double delta)
	{
		var newDelta = (float)delta;
		InputManager.Update(newDelta);
		
		//协程更新
		if (_coroutineList != null)
		{
			ProxyCoroutineHandler.ProxyUpdateCoroutine(ref _coroutineList, newDelta);
		}
	}

	/// <summary>
	/// 创建新的 World 对象, 相当于清理房间
	/// </summary>
	public World CreateNewWorld()
	{
		if (World != null)
		{
			World.QueueFree();
		}
		World = ResourceManager.LoadAndInstantiate<World>(ResourcePath.scene_World_tscn);
		SceneRoot.AddChild(World);
		return World;
	}

	/// <summary>
	/// 销毁 World 对象, 相当于清理房间
	/// </summary>
	public void DestroyWorld()
	{
		if (World != null)
		{
			World.QueueFree();
		}

		World = null;
	}
	
	/// <summary>
	/// 将 viewport 以外的全局坐标 转换成 viewport 内的全局坐标
	/// </summary>
	public Vector2 GlobalToViewPosition(Vector2 globalPos)
	{
		//return globalPos;
		return globalPos / PixelScale - (ViewportSize / 2) + GameCamera.Main.GlobalPosition;
	}

	/// <summary>
	/// 将 viewport 以内的全局坐标 转换成 viewport 外的全局坐标
	/// </summary>
	public Vector2 ViewToGlobalPosition(Vector2 viewPos)
	{
		// 3.5写法
		//return (viewPos - GameCamera.Main.GlobalPosition + (GameConfig.ViewportSize / 2)) * GameConfig.WindowScale - GameCamera.Main.SubPixelPosition;
		return (viewPos - (GameCamera.Main.GlobalPosition + GameCamera.Main.Offset) + (ViewportSize / 2)) * PixelScale;
	}
	
	/// <summary>
	/// 开启一个协程, 返回协程 id, 协程是在普通帧执行的, 支持: 协程嵌套, WaitForSeconds, WaitForFixedProcess, Task, SignalAwaiter
	/// </summary>
	public long StartCoroutine(IEnumerator able)
	{
		return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able);
	}

	/// <summary>
	/// 根据协程 id 停止协程
	/// </summary>
	public void StopCoroutine(long coroutineId)
	{
		ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
	}
    
	/// <summary>
	/// 停止所有协程
	/// </summary>
	public void StopAllCoroutine()
	{
		ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
	}

	//初始化房间配置
	private void InitRoomConfig()
	{
		//加载房间配置信息
		var file = FileAccess.Open(ResourcePath.resource_map_RoomConfig_json, FileAccess.ModeFlags.Read);
		var asText = file.GetAsText();
		RoomConfig = JsonSerializer.Deserialize<Dictionary<string, DungeonRoomGroup>>(asText);
		file.Dispose();

		//初始化RoomConfigMap
		RoomConfigMap = new Dictionary<string, DungeonRoomSplit>();
		foreach (var dungeonRoomGroup in RoomConfig)
		{
			foreach (var dungeonRoomType in Enum.GetValues<DungeonRoomType>())
			{
				foreach (var dungeonRoomSplit in dungeonRoomGroup.Value.GetRoomList(dungeonRoomType))
				{
					RoomConfigMap.Add(dungeonRoomSplit.ScenePath, dungeonRoomSplit);
				}
			}
		}
	}

	//窗体大小改变
	private void OnWindowSizeChanged()
	{
		var size = GetWindow().Size;
		ViewportSize = size / PixelScale;
		RefreshSubViewportSize();
	}
	
	//刷新视窗大小
	private void RefreshSubViewportSize()
	{
		var s = new Vector2I((int)ViewportSize.X, (int)ViewportSize.Y);
		s.X = s.X / 2 * 2;
		s.Y = s.Y / 2 * 2;
		SubViewport.Size = s;
		SubViewportContainer.Scale = new Vector2(PixelScale, PixelScale);
		SubViewportContainer.Size = s;
	}

	//初始化鼠标
	private void InitCursor()
	{
		Input.MouseMode = Input.MouseModeEnum.Hidden;
		Cursor = ResourceManager.LoadAndInstantiate<Cursor>(ResourcePath.prefab_Cursor_tscn);
		var cursorLayer = new CanvasLayer();
		cursorLayer.Name = "CursorLayer";
		cursorLayer.Layer = UiManager.GetUiLayer(UiLayer.Pop).Layer + 10;
		AddChild(cursorLayer);
		cursorLayer.AddChild(Cursor);
	}

#if TOOLS
	//调试模式下, 指定生成哪些房间
	private void InitDesignatedRoom()
	{
		if (DesignatedRoom != null && DesignatedRoom.Length > 0)
		{
			var list = new List<DungeonRoomSplit>();
			foreach (var packedScene in DesignatedRoom)
			{
				if (RoomConfigMap.TryGetValue(packedScene.ResourcePath, out var dungeonRoomSplit))
				{
					list.Add(dungeonRoomSplit);
				}
			}
			DungeonGenerator.SetDesignatedRoom(list);
		}
	}
#endif

}