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; AudioMgr.init(); this.InitGameMode(); this.CheckGuide(); } 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); if (gameType > 0) { GameObject.Instantiate(Resources.Load("Prefabs/Views/GameRuleView")); } } public void StopGame() { Destroy(GameObject.FindObjectOfType()); Arrow[] arrows = GameObject.FindObjectsOfType(); foreach(var arrow in arrows) { Destroy(arrow); } } public void SetTargetDistance(Transform target, float value) { Vector3 v3 = target.transform.localPosition; v3.x = 7.718f + (-17.12f - 7.718f) * ((value - 10f) / 60f); target.transform.localPosition = v3; } bool guideFinish = false; public void CheckGuide() { int deviceCalibrateGuideFinish = PlayerPrefs.GetInt("DeviceCalibrateGuide", 0); if (deviceCalibrateGuideFinish != 1) { DeviceCalibrateView.Create(); return; } int gameRuleGuideFinish = PlayerPrefs.GetInt("GameRuleGuide" + gameType, 0); if (gameRuleGuideFinish != 1) { GameRuleView gameRuleView = GameObject.FindObjectOfType(); if (gameRuleView) { gameRuleView.Click(); return; } } guideFinish = true; gameMode.Start(); } public void FinishGameRuleGuide() { if (guideFinish) return; PlayerPrefs.SetInt("GameRuleGuide" + gameType, 1); CheckGuide(); } public void FinishDeviceCalibrateGuide() { if (guideFinish) return; PlayerPrefs.SetInt("DeviceCalibrateGuide", 1); 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 abstract class GameMode { public GameMgr gameMgr; public bool pauseTimeCounting = false; 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 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) {} public override bool DoNextShoot() { return true; } public override object[] Settle() { return null; } } /**单人限时模式 */ public class TimeLimitGameMode : GameMode { public int score = 0; int oneStarScore = 10; float time = 60; public TimeLimitGameMode(GameMgr gameMgr) : base(gameMgr) { //记录可射击的靶子 TargetBody 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); } public override void HitTarget(int score) { this.score += score; } public override bool DoNextShoot() { return !GameMgr.ins.gameOver; } public override object[] Settle() { int starCount = this.score / this.oneStarScore; string highestScoreKey = "TimeLimitGameHighestScore"; int highestScore = PlayerPrefs.GetInt(highestScoreKey, 0); if (this.score > highestScore) { PlayerPrefs.SetInt(highestScoreKey, this.score); } 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 int GetHighestScore() { string highestScoreKey = "TimeLimitGameHighestScore"; return PlayerPrefs.GetInt(highestScoreKey, 0); } 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 currentPlayerID = 1; public int[] totalScores = {0, 0}; public int[] currentScores = {0, 0}; public int round = 1; float[] targetDistancesOnRound = {10, 20, 30, 50, 70, 70}; int maxRound = 5; int shootCount = 0; int maxShootCount = 3; public float singleShootReadyTime = 20; public float singleShootReadyMaxTime = 20; bool singleShootTimeRunning = false; public static int[] playerRoleIDs = {1, 2}; string[] gameRes = {"平局", "平局"}; //记录可射击的靶子 TargetBody targetBody; public PKGameMode(GameMgr gameMgr) : base(gameMgr) { //记录可射击的靶子 targetBody = GameObject.Find("GameArea/010/TargetBody").GetComponent(); GameObject.Find("Main Camera/ArmBow").GetComponent().validTargets.Add(targetBody); gameMgr.SetTargetDistance(targetBody.transform.parent, targetDistancesOnRound[round - 1]); //添加游戏界面 GameObject view = Resources.Load("Prefabs/Views/PKGameView"); GameObject.Instantiate(view); //禁止动作-相机和手臂 BanBowReady(); } public override void Start() { //添加预备界面 AddReadyView(); } void AddReadyView() { GameObject view = Resources.Load("Prefabs/Views/PKGameReadyView"); GameObject.Instantiate(view); } void BanBowReady() { ArmBow armBow = GameObject.FindObjectOfType(); armBow.banReady = true; armBow.banShoot = true; } public void UnbanBowReady() { ArmBow armBow = GameObject.FindObjectOfType(); armBow.banReady = false; armBow.banShoot = false; GameObject.FindObjectOfType().readyShoot(); } public override void HitTarget(int score) { currentScores[currentPlayerID - 1] += score; shootCount++; } public override bool DoNextShoot() { bool nextPlayer = false; bool nextRound = false; bool gameEnd = false; //游戏是否结束 if (shootCount == maxShootCount) { shootCount = 0; //当局是否结束 if (currentPlayerID == 2) { currentPlayerID = 1; 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] && round == maxRound) { if (round == 5) { maxShootCount = 1; maxRound = 6; } else { gameEnd = true; gameRes = new string[]{"平局", "平局"}; } } else if (totalScores[0] >= 6) { gameEnd = true; gameRes = new string[]{"胜利", "失败"}; } else if (totalScores[1] >= 6) { gameEnd = true; gameRes = new string[]{"失败", "胜利"}; } } else { currentPlayerID = 2; } nextPlayer = true; } if (gameEnd) { gameMgr.gameOver = true; gameMgr.StopGame(); GameObject view = Resources.Load("Prefabs/Views/PKGameSettleView"); GameObject.Instantiate(view); return false; } else if (nextPlayer) { //进入下一回合? if (nextRound) { round++; currentScores[0] = currentScores[1] = 0; gameMgr.SetTargetDistance(targetBody.transform.parent, targetDistancesOnRound[round - 1]); } //准备切换玩家 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; } }