using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using UnityEngine.UI; public class GameMgr : MonoBehaviour { public static bool debugInEditor = false; public static int gameType = 0; public GameMode gameMode; public bool gameOver = false; public static GameMgr ins; void Awake() { ins = this; if (Application.platform == RuntimePlatform.WindowsEditor) { debugInEditor = true; } AudioMgr.Init(); this.InitGameMode(); // if (debugInEditor) { // guideFinish = true; // gameMode.Start(); // } else { // if (!BluetoothStatus.IsAllConnected()) { // GameObject view = DeviceReconnectView.Show(); // if (view) { // view.GetComponent().onComplete = CheckGuide; // } // } else { // this.CheckGuide(); // } // } guideFinish = true; gameMode.Start(); } void Start() { if (ShootCheck.ins) ShootCheck.ins.AdjustNormalOrHightMode(); } void FixedUpdate() { gameMode.Update(); } void InitGameMode() { if (gameType == 0) gameMode = new GameModeTest(this); if (gameType == 1) gameMode = new TimeLimitGameMode(this); if (gameType == 2) gameMode = new PKGameMode(this); } public void StopGame() { Destroy(GameObject.FindObjectOfType()); Arrow[] arrows = GameObject.FindObjectsOfType(); foreach(var arrow in arrows) { Destroy(arrow); } } bool guideFinish = false; public void CheckGuide() { if (gameType > 0) { if (!LoginMgr.myUserInfo.deviceCalibrateGuideFinish) { DeviceCalibrateView.Create(); return; } bool gameRuleGuideFinish = (bool)LoginMgr.myUserInfo.GetType().GetField($"gameRule{GameMgr.gameType}GuideFinish").GetValue(LoginMgr.myUserInfo); if (!gameRuleGuideFinish) { GameRuleView.Create(); return; } } guideFinish = true; gameMode.Start(); } public void FinishGameRuleGuide() { if (guideFinish) return; LoginMgr.myUserInfo.GetType().GetField($"gameRule{GameMgr.gameType}GuideFinish").SetValue(LoginMgr.myUserInfo, true); LoginMgr.myUserInfo.Save(); CheckGuide(); } public void FinishDeviceCalibrateGuide() { if (guideFinish) return; LoginMgr.myUserInfo.deviceCalibrateGuideFinish = true; LoginMgr.myUserInfo.Save(); CheckGuide(); } HashSet gamePauseLockers = new HashSet(); public bool gamePause { get { return gamePauseLockers.Count > 0; } } public void addLockerForGamePause(Object o) { gamePauseLockers.Add(o); if (gamePauseLockers.Count > 0) { Time.timeScale = 0; } } public void removeLockerForGamePause(Object o) { gamePauseLockers.Remove(o); if (gamePauseLockers.Count == 0) { Time.timeScale = 1; } } //现实的计量值转游戏场景的计量值(米) public static float RealSizeToGameSize(float realSize) { return realSize * 0.413966f; } //游戏场景的计量值转现实的计量值(米) public static float GameSizeToRealSize(float gameSize) { return gameSize / 0.413966f; } } public abstract class GameMode { public GameMgr gameMgr; public bool pauseTimeCounting { get { return timeCountingPauseLockers.Count > 0; } } HashSet timeCountingPauseLockers = new HashSet(); public void PauseTimeCounting(System.Object o) { timeCountingPauseLockers.Add(o); } public void ResumeTimeCounting(System.Object o) { timeCountingPauseLockers.Remove(o); } public GameMode(GameMgr gameMgr) { this.gameMgr = gameMgr; } public abstract void HitTarget(int score); public abstract bool DoNextShoot(); public abstract object[] Settle(); public virtual void Start() {} public virtual void Update() {} public virtual void onBowReady() {} public virtual void onBowShoot() {} public void BanBowReady() { PauseTimeCounting(this); ArmBow armBow = GameObject.FindObjectOfType(); armBow.banReady = true; armBow.banShoot = true; } public void UnbanBowReady() { ResumeTimeCounting(this); ArmBow armBow = GameObject.FindObjectOfType(); armBow.banReady = false; armBow.banShoot = false; GameObject.FindObjectOfType().readyShoot(); } } public class GameModeTest : GameMode { public GameModeTest(GameMgr gameMgr) : base(gameMgr) { //记录可射击的靶子 TargetBody targetBody = GameObject.Find("GameArea/010/TargetBody").GetComponent(); GameObject.Find("Main Camera/ArmBow").GetComponent().validTargets.Add(targetBody); } public override void HitTarget(int score) { HitTargetNumber.Create(score); } public override bool DoNextShoot() { return true; } public override object[] Settle() { return null; } } /**单人限时模式 */ public class TimeLimitGameMode : GameMode { public static int[] distanceCanSelected = {10, 20, 30, 50, 70}; public static int distance = 10; public int score = 0; int oneStarScore = 10; float time = 60; TargetBody targetBody; public TimeLimitGameMode(GameMgr gameMgr) : base(gameMgr) { //记录可射击的靶子 targetBody = GameObject.Find("GameArea/010/TargetBody").GetComponent(); GameObject.Find("Main Camera/ArmBow").GetComponent().validTargets.Add(targetBody); //添加游戏界面 GameObject view = Resources.Load("Prefabs/Views/TimeLimitGameView"); GameObject.Instantiate(view); BanBowReady(); } public override void Start() { UnbanBowReady(); GameObject.Instantiate(Resources.Load("Prefabs/Views/TimeLimitGameDistanceSelectView")); } public void RefreshTargetDistance() { targetBody.SetDistance(distance); } public override void HitTarget(int score) { this.score += score; HitTargetNumber.Create(score); } public override bool DoNextShoot() { return !GameMgr.ins.gameOver; } public override object[] Settle() { int starCount = this.score / this.oneStarScore; int highestScore = LoginMgr.myUserInfo.timeLimitGameHighestScore; if (this.score > highestScore) { LoginMgr.myUserInfo.timeLimitGameHighestScore = this.score; LoginMgr.myUserInfo.Save(); } return new object[]{starCount, this.score}; } public override void Update() { if (gameMgr.gameOver || pauseTimeCounting) return; if (this.time > 0) { this.time -= Time.deltaTime; } else { this.time = 0; gameMgr.gameOver = true; gameMgr.StopGame(); //添加结算界面 GameObject view = Resources.Load("Prefabs/Views/TimeLimitGameSettleView"); GameObject.Instantiate(view); } } public string GetTimeStr() { int seconds = (int) Mathf.Ceil(this.time); string str = ""; int m = seconds / 60; if (m < 10) { str += 0; } str += m; str += " : "; int s = seconds % 60; if (s < 10) { str += 0; } str += s; return str; } } /**双人PK模式 */ public class PKGameMode : GameMode { public int currentPlayerIndex = 0; public int[] totalScores = {0, 0}; public int[] currentScores = {0, 0}; public int round = 1; public int showRoundValue = 0; //回合开始提示值,如果已经提示,则showRoundValue == round float[] targetDistancesOnRound = {10, 20, 30, 50, 70, 70}; int maxRound = 5; int[] shootCount = {0, 0}; int maxShootCount = 3; public float singleShootReadyTime = 20; public float singleShootReadyMaxTime = 20; bool singleShootTimeRunning = false; public static int[] playerRoleIDs = {1, 2}; string[] gameRes = {"平局", "平局"}; //玩家出场顺序 Queue appearPlayerIndexes = new Queue(); //记录可射击的靶子 TargetBody targetBody; public PKGameMode(GameMgr gameMgr) : base(gameMgr) { InitAppearPlayerIndexes(); currentPlayerIndex = appearPlayerIndexes.Dequeue(); //记录可射击的靶子 targetBody = GameObject.Find("GameArea/010/TargetBody").GetComponent(); GameObject.Find("Main Camera/ArmBow").GetComponent().validTargets.Add(targetBody); targetBody.SetDistance(targetDistancesOnRound[round - 1]); //添加游戏界面 GameObject view = Resources.Load("Prefabs/Views/PKGameView"); GameObject.Instantiate(view); //禁止动作-相机和手臂 BanBowReady(); } public override void Start() { //添加预备界面 AddReadyView(); } int[] sequencePlayerIndexes = new int[]{0, 1}; void InitAppearPlayerIndexes() { if (round >= 2) { if (totalScores[0] < totalScores[1]) { sequencePlayerIndexes = new int[]{0, 1}; } else if (totalScores[1] < totalScores[0]) { sequencePlayerIndexes = new int[]{1, 0}; } } for (int i = 0; i < maxShootCount; i++) { appearPlayerIndexes.Enqueue(sequencePlayerIndexes[0]); appearPlayerIndexes.Enqueue(sequencePlayerIndexes[1]); } } void AddReadyView() { GameObject view = Resources.Load("Prefabs/Views/PKGameReadyView"); GameObject.Instantiate(view); } public override void HitTarget(int score) { currentScores[currentPlayerIndex] += score; shootCount[currentPlayerIndex]++; HitTargetNumber.Create(score); } public override bool DoNextShoot() { if (gameMgr.gameOver) return false; bool nextRound = false; bool gameEnd = false; //游戏是否结束 if (shootCount[0] == maxShootCount && shootCount[1] == maxShootCount ) { shootCount = new int[]{0, 0}; nextRound = true; //更新总比分 if (currentScores[0] == currentScores[1]) { totalScores[0] += 1; totalScores[1] += 1; } else if (currentScores[0] > currentScores[1]) { totalScores[0] += 2; } else if (currentScores[0] < currentScores[1]) { totalScores[1] += 2; } //根据总比分判断游戏是否结束 if (totalScores[0] == totalScores[1]) { if (round == maxRound) { if (round == 5) { maxShootCount = 1; maxRound = 6; } else { gameEnd = true; gameRes = new string[]{"平局", "平局"}; } } } else if (totalScores[0] >= 6 && totalScores[0] > totalScores[1]) { gameEnd = true; gameRes = new string[]{"胜利", "失败"}; } else if (totalScores[1] >= 6 && totalScores[1] > totalScores[0]) { gameEnd = true; gameRes = new string[]{"失败", "胜利"}; } } if (gameEnd) { gameMgr.gameOver = true; gameMgr.StopGame(); GameObject view = Resources.Load("Prefabs/Views/PKGameSettleView"); GameObject.Instantiate(view); return false; } else { //进入下一回合? if (nextRound) { round++; currentScores[0] = currentScores[1] = 0; InitAppearPlayerIndexes(); targetBody.SetDistance(targetDistancesOnRound[round - 1]); } //本轮玩家登记 currentPlayerIndex = appearPlayerIndexes.Dequeue(); //准备切换玩家 BanBowReady(); AddReadyView(); //清除箭矢 Arrow[] arrows = GameObject.FindObjectsOfType(); foreach (var arrow in arrows) { try { GameObject.Destroy(arrow.gameObject); } catch (UnityException e) { Debug.Log("Delete Arrow Error\n" + e.Message); } } } return true; } public override object[] Settle() { return gameRes; } public override void Update() { if (singleShootTimeRunning && !pauseTimeCounting) { singleShootReadyTime -= Time.deltaTime; if (singleShootReadyTime <= 0) { singleShootReadyTime = 0; singleShootTimeRunning = false; HitTarget(0); BanBowReady(); //超时显示 Text timeoutText = PKGameView.ins.transform.Find("TimeoutText").GetComponent(); Sequence seq = DOTween.Sequence(); seq.Append(timeoutText.DOFade(1, 0.5f)); seq.AppendInterval(1); seq.Append(timeoutText.DOFade(0, 0.5f)); seq.AppendCallback(delegate(){ if (DoNextShoot()) { UnbanBowReady(); } }); } } } public string GetTimeStr() { int seconds = (int) Mathf.Ceil(this.singleShootReadyTime); string str = ""; int m = seconds / 60; if (m < 10) { str += 0; } str += m; str += " : "; int s = seconds % 60; if (s < 10) { str += 0; } str += s; return str; } public override void onBowReady() { singleShootReadyTime = singleShootReadyMaxTime; singleShootTimeRunning = true; } public override void onBowShoot() { singleShootTimeRunning = false; } }