Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / GameApplication.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Config;
using Godot;
using UI.BottomTips;

public partial class GameApplication : Node2D, ICoroutine
{
	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>
	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;

		//初始化配置表
		ExcelConfig.Init();
		//初始化房间配置数据
		InitRoomConfig();
		//初始化 ActivityObject
		ActivityObject.InitActivity();
		//初始化武器数据
		Weapon.InitWeaponAttribute();
		
		DungeonConfig = new DungeonConfig();
		DungeonConfig.GroupName = RoomConfig.FirstOrDefault().Key;
		DungeonConfig.RoomCount = 20;
	}
	
	public override void _EnterTree()
	{
		//随机化种子
		//GD.Randomize();
		//固定帧率
		Engine.MaxFps = 60;
		//调试绘制开关
		ActivityObject.IsDebug = Debug;
		//Engine.TimeScale = 0.2f;

		ImageCanvas.Init(GetTree().CurrentScene);
		
		//窗体大小改变
		GetWindow().SizeChanged += OnWindowSizeChanged;
		RefreshSubViewportSize();
        
		//初始化ui
		UiManager.Init();
		// 初始化鼠标
		InitCursor();
		//地牢管理器
		DungeonManager = new DungeonManager();
		DungeonManager.Name = "DungeonManager";
		SceneRoot.AddChild(DungeonManager);

		MapProjectManager.Init();
		BottomTipsPanel.Init();
		//打开主菜单Ui
		UiManager.Open_Main();
		//UiManager.Open_MapEditorProject();
	}

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

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

	/// <summary>
	/// 销毁 World 对象, 相当于清理房间
	/// </summary>
	public void DestroyWorld()
	{
		if (World != null)
		{
			ClearWorld();
			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;
	}
	
	public long StartCoroutine(IEnumerator able)
	{
		return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able);
	}
	
	public void StopCoroutine(long coroutineId)
	{
		ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
	}

	public bool IsCoroutineOver(long coroutineId)
	{
		return ProxyCoroutineHandler.ProxyIsCoroutineOver(ref _coroutineList, coroutineId);
	}

	public void StopAllCoroutine()
	{
		ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
	}

	public void SetRoomConfig(Dictionary<string,DungeonRoomGroup> roomConfig)
	{
		RoomConfig = roomConfig;
		InitReadyRoom();
	}

	//初始化房间配置
	private void InitRoomConfig()
	{
		//加载房间配置信息
		var asText = ResourceManager.LoadText("res://resource/map/tileMaps/" + GameConfig.RoomGroupConfigFile);
		RoomConfig = JsonSerializer.Deserialize<Dictionary<string, DungeonRoomGroup>>(asText);

		InitReadyRoom();
	}
	
	//初始化房间数据
	private void InitReadyRoom()
	{
		foreach (var dungeonRoomGroup in RoomConfig)
		{
			RemoveUnreadyRooms(dungeonRoomGroup.Value.BattleList);
			RemoveUnreadyRooms(dungeonRoomGroup.Value.InletList);
			RemoveUnreadyRooms(dungeonRoomGroup.Value.OutletList);
			RemoveUnreadyRooms(dungeonRoomGroup.Value.BossList);
			RemoveUnreadyRooms(dungeonRoomGroup.Value.ShopList);
			RemoveUnreadyRooms(dungeonRoomGroup.Value.RewardList);
			RemoveUnreadyRooms(dungeonRoomGroup.Value.EventList);
		}
	}
	
	//移除未准备好的房间
	private void RemoveUnreadyRooms(List<DungeonRoomSplit> roomInfos)
	{
		for (var i = 0; i < roomInfos.Count; i++)
		{
			if (roomInfos[i].ErrorType != RoomErrorType.None) //存在错误
			{
				roomInfos.RemoveAt(i);
				i--;
			}
		}
	}

	//窗体大小改变
	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()
	{
		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);
	}

	//清理世界
	private void ClearWorld()
	{
		
		var childCount = World.NormalLayer.GetChildCount();
		for (var i = 0; i < childCount; i++)
		{
			var c = World.NormalLayer.GetChild(i);
			if (c is IDestroy destroy)
			{
				destroy.Destroy();
			}
		}
		childCount = World.YSortLayer.GetChildCount();
		for (var i = 0; i < childCount; i++)
		{
			var c = World.YSortLayer.GetChild(i);
			if (c is IDestroy destroy)
			{
				destroy.Destroy();
			}
		}
	}
}