using System; using System.Collections; using System.Collections.Generic; using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines; using Common; using DragonLi.Core; using Mirror; using UnityEngine; using UnityEngine.PlayerLoop; using XPlugin.Data.JsonLiteDB; using static XPlugin.Data.JsonLiteDB.JsonLiteDB; using LitJson; using Pathfinding; using DarkTonic.MasterAudio; using NaughtyAttributes; using UnityEngine.UIElements; /// /// 游戏状态 /// public enum GameState { None = 0, Playing = 1, /// /// 胜利 /// Victory = 2, /// /// 失败 /// Failur = 3, Settle } public class GameManager : NetworkBehaviour { public static GameManager Ins { get; private set; } #region 预制体 public GameObject PowerCorePre; public GameObject DoorPre; public GameObject BombPre; // 炮塔预制体集合 public GameObject[] TowerPres; // 怪物预制集合 public GameObject[] EnemyPres; // 怪物ui预制体 public GameObject EnemyUIPre; #endregion // json数据库 private JsonLiteDB DB; // 怪物信息集合 public Dictionary> EnemyInfos = new Dictionary>(); // 炮塔信息集合 public Dictionary> TowerInfos = new Dictionary>(); // 枪械信息集合 public Dictionary> GunInfos = new Dictionary>(); // 子弹信息集合 public Dictionary> BulletInfos = new Dictionary>(); // 防线信息 public List DefenseInfos = new List(); // 剧情信息 public Dictionary> CombatUnitInfos = new Dictionary>(); /// /// 敌人自增 /// private int enemyIndex = 0; /// /// 所有敌人 /// public Dictionary EnemyList = new Dictionary(); /// /// 所有敌人UI /// public Dictionary EnemyUIList = new Dictionary(); /// /// 炮塔自增 /// public int towerIndex = 0; /// /// 所有炮塔 /// public Dictionary TowerList = new Dictionary(); public Dictionary> TowerList2 = new Dictionary>(); public Dictionary SettleInfos = new Dictionary(); /// /// 波次自增 /// [SyncVar] public int roundIndex = 0; // 游玩结束时间 [NonSerialized] [SyncVar] public long vistEnd = 0; [SyncVar] public string settleData = ""; [SyncVar] public GameState gameState = GameState.None; [SoundGroup] public string JointIn; [SoundGroup] public string roundSound; [NonSerialized] [SyncVar] public int blueScore = 0; [NonSerialized] [SyncVar] public int redScore = 0; void Awake() { Ins = this; } void Start() { if (isClient) { AuthorPanel.Show(); } } /// /// 创建门 /// public void CreateDoor() { UpdateConf(); GameObject door = Instantiate(DoorPre); NetworkServer.Spawn(door); door.transform.position = new Vector3(0, 0.05f, 0.2f); } /// /// 创建初回合 /// public void CreateFirstRound() { SetGameState(GameState.Playing); roundIndex = 0; CreateRound(roundIndex); PlaySound2DRPC(roundSound); RpcMessageRound(); } /// /// 创建下一回合 /// public void CreateNextRound() { roundIndex++; if (CreateRound(roundIndex)) { PlaySound2DRPC(roundSound); RpcMessageRound(); } else { GameOver(GameState.Victory); } } /// /// 创建回合 /// public bool CreateRound(int progress) { // 修复场上所有炮塔 foreach (Tower tower in TowerList.Values) { if (tower.type != TowerType.PowerCore) { // 只恢复被击毁的 if (tower.state == TowerState.Broken) { tower.RepairImm(); } } } bool created = false; CombatUnitInfos.TryGetValue(progress, out List combatUnitInfos); if (combatUnitInfos != null) { created = true; foreach (CombatUnitInfo combatUnitInfo in combatUnitInfos) { CoroutineTaskManager.Instance.WaitSecondTodo(() => { if (combatUnitInfo.Special == 0) { CreateEnemy( (EnemyType)combatUnitInfo.EnemyType, combatUnitInfo.BornPos, combatUnitInfo.BornAngleY ); } else { CreateAir( (EnemyType)combatUnitInfo.EnemyType, combatUnitInfo.BornPos, combatUnitInfo.BornAngleY); } }, combatUnitInfo.BornTime); } } return created; } [Server] public void GameStart() { gameState = GameState.Playing; vistEnd = (long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1))).TotalSeconds + GameLocal.Ins.vistAllTime; ChangeBgmRpc(1); // CreateTowers(); AstarPath.active.Scan(); // CreateFirstRound(); // 延迟1s后给所有人发放武器 CoroutineTaskManager.Instance.WaitSecondTodo(() => { GivePistol(); RpcShowSettle(); }, 1f); CoroutineTaskManager.Instance.WaitSecondTodo(() => { GameOver(GameState.Settle); }, 60 * 10f); } [ClientRpc] public void RpcShowSettle() { GameLocal.Ins.Settle.SetActive(true); } [ClientRpc] public void GivePistol() { Debug.Log("创建武器中..."); GameLocal.Ins.self.PickUpGun(GunType.Pistol, -999); } [Server] public void SetGameState(GameState state) { gameState = state; } //1.游戏时间到 //2.所有怪物被消灭 //3.玩家被消灭 //以上都要跳出结算 [Server] public void GameOver(GameState state) { gameState = state; // foreach (string key in SettleInfos.Keys) // { // string[] titles = { "小菜一碟", "轻松拿捏", "荣耀勇士", "掌控全场", "队伍灵魂" // ,"荣耀勇士", "团队之星", "颜值担当", "枪法如神", "弹无虚发", "精准猎手", "铁血战士", "无畏先锋", "无所畏惧" }; // SetTitle(key, titles[UnityEngine.Random.Range(0, titles.Length)]); // SetPlayerName(key); // } // string jsonStr = JsonMapper.ToJson(SettleInfos); // settleData = jsonStr; // //结算页面 //RpcShow(); if (blueScore >= redScore) { RpcShowWin(true); } else { RpcShowWin(false); } Debug.Log("游戏结束,60秒后退出"); CoroutineTaskManager.Instance.WaitSecondTodo(() => { Debug.Log("正在退出游戏..."); Application.Quit(); }, 60f); } [ClientRpc] public void RpcShowWin(bool isBlue) { GameLocal.Ins.Settle.SetActive(false); if (isBlue) { GameLocal.Ins.BlueWin.SetActive(true); } else { GameLocal.Ins.RedWin.SetActive(true); } } [ClientRpc] public void RpcShow() { SettlePanel.Show(); } /// /// 下一波进攻开始 /// [ClientRpc] public void RpcMessageRound() { CoroutineTaskManager.Instance.WaitSecondTodo(() => { DragonLi.Core.EventDispatcher.TriggerEvent("NewWaveStart", roundIndex); }, 0.5f); } [ClientRpc] public void ChangeBgmRpc(int i) { GameLocal.Ins.BGMState.StateChange(i); } /// /// 创建炮塔 /// public void CreateTowers() { foreach (DefenseInfo defenseInfo in DefenseInfos) { GameObject tower = Instantiate(TowerPres[(int)defenseInfo.TowerType]); NetworkServer.Spawn(tower); tower.transform.position = defenseInfo.BornPos; tower.transform.eulerAngles = new Vector3(0, defenseInfo.BornAngleY, 0); towerIndex++; Tower towerScript = tower.GetComponent(); towerScript.OnSpawn(towerIndex, defenseInfo.TowerType, 1); TowerList.Add(towerIndex, towerScript); TowerList2.TryGetValue(defenseInfo.TowerType, out List towerList); if (towerList == null) { List list = new List(); list.Add(towerScript); TowerList2.Add(defenseInfo.TowerType, list); } else { towerList.Add(towerScript); } } } /// /// 创建敌方单位 /// public void CreateEnemy(EnemyType type, Vector3 pos, float angleY) { GameObject enemy = Instantiate(EnemyPres[(int)type]); NetworkServer.Spawn(enemy); enemy.transform.position = pos; enemy.transform.eulerAngles = new Vector3(0, angleY, 0); enemyIndex++; Enemy enemyScript = enemy.GetComponent(); enemyScript.OnSpawn(enemyIndex, type, 1); EnemyList.Add(enemyIndex, enemyScript); } /// /// 删除敌方单位 /// [Server] public void DeleteEnemy(int id) { GameObject enemy = EnemyList[id].gameObject; EnemyList.Remove(id); NetworkServer.Destroy(enemy); if (EnemyList.Count == 0) { CreateNextRound(); } } /// /// 痛击场上所有敌方单位 /// [Command(requiresAuthority = false)] public void DamageAllEnemy() { foreach (Enemy enemy in EnemyList.Values) { enemy.ApplyDamage(999999, null, null); } } /// /// 创建炮弹 /// public void CreateBomb(Vector3 pos, Vector3 angle) { GameObject bomb = Instantiate(BombPre); NetworkServer.Spawn(bomb); bomb.transform.position = pos; bomb.transform.eulerAngles = angle; } public void CreateAir(EnemyType type, Vector3 pos, float angleY) { GameObject enemy = Instantiate(EnemyPres[(int)type]); NetworkServer.Spawn(enemy); enemy.transform.position = pos; enemy.transform.eulerAngles = new Vector3(0, angleY, 0); Airdrop enemyScript = enemy.GetComponent(); enemyScript.OnSpawn(type, 1); } /// /// 更新配置表 /// public void UpdateConf() { string text = Resources.Load("Data").text; if (text != null) { ParseGameJson(text); } } public void ParseGameJson(string text) { DB = new JsonLiteDB(); DB.Load(text); TableReader infoReader = DB["EnemysInfo"].GetReader(); while (infoReader.Read()) { EnemyInfo info = new EnemyInfo(infoReader); EnemyInfos.TryGetValue((EnemyType)info.Type, out Dictionary infoList); if (infoList == null) { Dictionary list = new Dictionary(); list.Add(info.Lvl, info); EnemyInfos.Add((EnemyType)info.Type, list); } else { infoList.Add(info.Lvl, info); } } infoReader = DB["TowersInfo"].GetReader(); while (infoReader.Read()) { TowerInfo info = new TowerInfo(infoReader); TowerInfos.TryGetValue((TowerType)info.Type, out Dictionary infoList); if (infoList == null) { Dictionary list = new Dictionary(); list.Add(info.Lvl, info); TowerInfos.Add((TowerType)info.Type, list); } else { infoList.Add(info.Lvl, info); } } infoReader = DB["GunsInfo"].GetReader(); while (infoReader.Read()) { GunInfo info = new GunInfo(infoReader); GunInfos.TryGetValue((GunType)info.Type, out Dictionary infoList); if (infoList == null) { Dictionary list = new Dictionary(); list.Add(info.Lvl, info); GunInfos.Add((GunType)info.Type, list); } else { infoList.Add(info.Lvl, info); } } infoReader = DB["BulletsInfo"].GetReader(); while (infoReader.Read()) { BulletInfo info = new BulletInfo(infoReader); BulletInfos.TryGetValue((BulletType)info.Type, out Dictionary infoList); if (infoList == null) { Dictionary list = new Dictionary(); list.Add(info.Lvl, info); BulletInfos.Add((BulletType)info.Type, list); } else { infoList.Add(info.Lvl, info); } } infoReader = DB["DefensesInfo"].GetReader(); while (infoReader.Read()) { DefenseInfo info = new DefenseInfo(infoReader); DefenseInfos.Add(info); } infoReader = DB["StoryProgressInfo"].GetReader(); while (infoReader.Read()) { CombatUnitInfo info = new CombatUnitInfo(infoReader); CombatUnitInfos.TryGetValue(info.Belong, out List infoList); if (infoList == null) { List list = new List(); list.Add(info); CombatUnitInfos.Add(info.Belong, list); } else { infoList.Add(info); } } Debug.Log("游戏数值更新 -> complete"); } /// /// 获取范围内敌人 /// public int GetRangeEnemyId(Vector3 pos, float radius) { int res = -1; foreach (Enemy enemy in EnemyList.Values) { float dis = Vector3.Distance(enemy.transform.position, pos); if (dis <= radius) { radius = dis; res = enemy.id; break; } } return res; } [Server] public void CreateEnemyUI(Enemy enemy) { GameObject enemyUI = Instantiate(EnemyUIPre); NetworkServer.Spawn(enemyUI); EnemyUI enemyUIScript = enemyUI.GetComponent(); enemyUIScript.Init(enemy); EnemyUIList.Add(enemy.id, enemyUIScript); } [Server] public void DeleteEnemyUI(int id) { GameObject enemyUI = EnemyUIList[id].gameObject; EnemyUIList.Remove(id); NetworkServer.Destroy(enemyUI); } [ClientRpc] public void RpcShowHUD() { // HUDPanel.Show(); } #region 空投道具 /// /// 修复炮塔 /// public void RepairTower() { } /// /// 进入联控 /// [Server] public void JoinControlTower(int playerIndex) { PlayJointMusic(); // 修改所有炮塔模式 foreach (Tower tower in TowerList.Values) { if (tower.controllerId == -1) { tower.controllerId = playerIndex; tower.mode = TowerMode.Joint; } } TriggerEvent("JoinControlStart", playerIndex); CoroutineTaskManager.Instance.WaitSecondTodo(() => { ChangeBgmRpc(1); foreach (Tower tower in TowerList.Values) { if (tower.mode == TowerMode.Joint) { tower.controllerId = playerIndex; tower.mode = tower.originalMode; } TriggerEvent("JoinControlEnd", playerIndex); } }, 30f); } #endregion [ClientRpc] public void TriggerEvent(string key, int param) { DragonLi.Core.EventDispatcher.TriggerEvent(key, param); } public void AddScore(string index, int damage) { if (SettleInfos.ContainsKey(index)) { SettleInfos[index].Score += damage; } string jsonStr = JsonMapper.ToJson(SettleInfos); settleData = jsonStr; } public void SetTitle(string index, string title) { if (SettleInfos.ContainsKey(index)) { SettleInfos[index].Title = title; } Debug.Log(SettleInfos); } public void SetPlayerName(string index) { if (SettleInfos.ContainsKey(index)) { SettleInfos[index].playerName = int.Parse(index); } } [Server] public void AddData(int playerIndex) { SettleInfos.Add(playerIndex.ToString(), new SettleInfo()); } public string SerializeSettleInfos() { return JsonUtility.ToJson(SettleInfos); } #region 工具 public string GetLessTimeStr() { string res = ""; if (gameState == GameState.Playing) { res = FormatTime((int)(vistEnd - DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds)); } return res; } public int GetLessTimeSeconds() { if (isServer) { return (int)(vistEnd - NetworkTime.time); } else { return (int)(vistEnd - NetworkClient.connection.remoteTimeStamp); } //return (int)(vistEnd - DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds); } // 时分秒 public string FormatTime(int totalSeconds) { //确保时间不为负 totalSeconds = Mathf.Max(0, totalSeconds); int hours = totalSeconds / 3600; // string hh = hours < 10 ? "0" + hours : hours.ToString(); int minutes = (totalSeconds - hours * 3600) / 60; string mm = minutes < 10f ? "0" + minutes : minutes.ToString(); int seconds = totalSeconds - hours * 3600 - minutes * 60; string ss = seconds < 10 ? "0" + seconds : seconds.ToString(); return string.Format("{0}:{1}", mm, ss); } #endregion [ClientRpc] public void PlaySound2DRPC(string sound) { MasterAudio.PlaySound(sound); } [ClientRpc] public void PlayJointMusic() { MasterAudio.PlaySound(JointIn); GameLocal.Ins.BGMState.StateChange(2); } [SyncVar] private int syncRemainingTime; void Update() { if (isServer) { //服务器计算剩余时间并同步 syncRemainingTime = GetLessTimeSeconds(); GameLocal.Ins.curGameTime+=Time.deltaTime; } } }