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; using Random = UnityEngine.Random; /// /// 游戏状态 /// public enum GameState { None = 0, Playing = 1, /// /// 胜利 /// Victory = 2, /// /// 失败 /// Failur = 3, Settle, Waiting= 5, } public class GameManager : NetworkBehaviour { public static GameManager Ins { get; private set; } #region 预制体 public GameObject redDoorPre; public GameObject blueDoorPre; public GameObject AirdropPlanePre;//空投飞机 public GameObject[] airdropItems;//空头道具 public GameObject startGameItemPre; // 怪物预制集合 public GameObject[] EnemyPres; // 怪物ui预制体 public GameObject EnemyUIPre; #endregion #region 实例化后物体 public GameObject redDoor; public GameObject blueDoor; #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 Dictionary> CombatUnitInfos = new Dictionary>(); /// /// 敌人自增 /// private int enemyIndex = 0; /// /// 所有敌人 /// public Dictionary EnemyList = new Dictionary(); /// /// 所有敌人UI /// public Dictionary EnemyUIList = new Dictionary(); public Dictionary SettleInfos = new Dictionary(); /// /// 波次自增 /// [SyncVar] public int roundIndex = 0; // 游玩结束时间 [NonSerialized] [SyncVar] public long vistEnd = 0; // 总游玩时长 private int vistAllTime = (int)(60 * 10f); [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(); } } /// /// 创建门 /// [Server] public void CreateDoor(Transform redPos, Transform bluePos,Transform startGamePos) { UpdateConf(); SetGameState(GameState.Waiting); if(!isServer) return; //创建红色门 redDoor = Instantiate(redDoorPre); NetworkServer.Spawn(redDoor); redDoor.transform.position = redPos.position; //创建蓝色门 blueDoor = Instantiate(blueDoorPre); NetworkServer.Spawn(blueDoor); blueDoor.transform.position = bluePos.position; //创建开始球 GameObject gameStartObj = Instantiate(startGameItemPre); NetworkServer.Spawn(gameStartObj); gameStartObj.transform.position = startGamePos.position; //测试枪械 GameLocal.Ins.self.GivePistol(); } /// /// 创建初回合 /// 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) { 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 + vistAllTime; _airdropTime = 25; _curAirdropTime = _airdropTime; ChangeBgmRpc(1); StartAirDrop(); AstarPath.active.Scan(); NetworkServer.Destroy(redDoor); NetworkServer.Destroy(blueDoor); // 延迟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); } } [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 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 CreateAirdropPlane(Vector3 startPos, Vector3 endPos) { GameObject airdropPlane = Instantiate(AirdropPlanePre); NetworkServer.Spawn(airdropPlane); airdropPlane.transform.position = startPos; AirdropPlane airdropPlaneScript = airdropPlane.GetComponent(); airdropPlaneScript.OnSpawn(endPos); } [Server] public void CreateAirDropItem(GunType type ,Vector3 startPos) { GameObject airdropItem = Instantiate(airdropItems[(int)type]); NetworkServer.Spawn(airdropItem); airdropItem.transform.position = startPos; } /// /// 删除敌方单位 /// [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 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["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); } } 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); PlayerUI 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(); } #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; private float _airdropTime;//空投时间 private float _curAirdropTime;//当前空头时间 private bool _isStartAirdrop;//是否开始倒计时空投 public void StartAirDrop() { _isStartAirdrop = true; } public void StopAirDrop() { _isStartAirdrop = false; } void Update() { if (isServer&& gameState==GameState.Playing&&_isStartAirdrop) { //服务器计算剩余时间并同步 syncRemainingTime = GetLessTimeSeconds(); _curAirdropTime+=Time.deltaTime; if (_curAirdropTime >= _airdropTime) { int airdropPosId = Random.Range(0, 4); int endAirdropPosId =0; if (airdropPosId == 0) endAirdropPosId = 1; if (airdropPosId == 1) endAirdropPosId = 0; if (airdropPosId == 2) endAirdropPosId = 3; if (airdropPosId == 3) endAirdropPosId = 2; CreateAirdropPlane(GameLocal.Ins.startPlanePos[airdropPosId].position,GameLocal.Ins.startPlanePos[endAirdropPosId].position); _curAirdropTime = 0; StopAirDrop(); } } } }