using Core.Game; using Core.Health; using DG.Tweening; using TowerDefense.Game; using TowerDefense.Level; using TowerDefense.Towers.Placement; using TowerDefense.UI.HUD; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; namespace TowerDefense.UI { /// /// UI to display the game over screen /// public class EndGameScreen : MonoBehaviour { /// /// AudioClip to play when victorious /// public AudioClip victorySound; /// /// AudioClip to play when failed /// public AudioClip defeatSound; /// /// AudioSource that plays the sound /// public AudioSource audioSource; /// /// The containing panel of the End Game UI /// public Canvas endGameCanvas; /// /// 游戏胜利时应该显示的Image. /// public Sprite victoryImg; /// /// 游戏失败时应该显示的Image. /// public Sprite failedImg; /// /// 显示游戏结果的图片. /// public Image gameResultImgOpp; public Image gameResultImgSelf; /// /// Panel that shows final star rating /// //public ScorePanel scorePanel; /// /// Name of level select screen /// public string menuSceneName = "MainManuScene"; /// /// Text to be displayed on popup /// public string levelCompleteText = "{0} COMPLETE!"; public string levelFailedText = "{0} FAILED!"; /// /// Background image /// public Image background; /// /// Color to set background /// //public Color winBackgroundColor; //public Color loseBackgroundColor; /// /// The Canvas that holds the button to go to the next level /// if the player has beaten the level /// //public Canvas nextLevelButton; /// /// Reference to the /// protected LevelManager m_LevelManager; /// /// Safely unsubscribes from events. /// Go back to the main menu scene /// 这个是旧版本的回到主菜单,暂时是用不上的。 /// public void GoToMainMenu() { DOTween.Clear(); UIStart.bFirstLoaded = false; UIStart.bGameStart = false; SafelyUnsubscribe(); SceneManager.LoadScene(menuSceneName); } /// /// Safely unsubscribes from events. /// Reloads the active scene /// public void RestartLevel() { UIStart.bFirstLoaded = false; UIStart.bGameStart = false; SafelyUnsubscribe(); string currentSceneName = SceneManager.GetActiveScene().name; SceneManager.LoadScene(currentSceneName); // 清空所有Tween数据: DOTween.Clear(); TowerPlacementGrid.GRID_OPENCASH_OPPO = 100; TowerPlacementGrid.GRID_OPENCASH_SELF = 100; // 关键数据需要重置: // 1: 局内升级相关的数据 SceneTowerLvl.clearInSceneTowerData(); // 2: GameUI需要清空. GameUI.instance.restartLevel(); // 3: AgentInsManager需要重来. AgentInsManager.instance.restartLevel(); // 4: 格子相关的数据重新开始. } /// /// 回到主界面的功能,暂时也使用重新开启新关卡. /// public void ReturnToMainMenu() { // 清空所有Tween数据: DOTween.Clear(); UIStart.bFirstLoaded = false; UIStart.bGameStart = false; TowerPlacementGrid.GRID_OPENCASH_OPPO = 100; TowerPlacementGrid.GRID_OPENCASH_SELF = 100; SafelyUnsubscribe(); SceneManager.LoadScene(menuSceneName); } /// /// Safely unsubscribes from events. /// Goes to the next scene if valid /// public void GoToNextLevel() { SafelyUnsubscribe(); if (!GameManager.instanceExists) { return; } GameManager gm = GameManager.instance; LevelItem item = gm.GetLevelForCurrentScene(); LevelList list = gm.levelList; int levelCount = list.Count; int index = -1; for (int i = 0; i < levelCount; i++) { if (item == list[i]) { index = i + 1; break; } } if (index < 0 || index >= levelCount) { return; } LevelItem nextLevel = gm.levelList[index]; SceneManager.LoadScene(nextLevel.sceneName); } /// /// Hide the panel if it is active at the start. /// Subscribe to the completed/failed events. /// protected void Start() { LazyLoad(); endGameCanvas.enabled = false; //nextLevelButton.enabled = false; //nextLevelButton.gameObject.SetActive(false); m_LevelManager.levelCompleted += Victory; m_LevelManager.levelFailed += Defeat; } /// /// Shows the end game screen /// protected void OpenEndGameScreen( bool victory ) { //endResultText = "关卡失败!"; //LevelItem level = GameManager.instance.GetLevelForCurrentScene(); endGameCanvas.enabled = true; int score = CalculateFinalScore(); // 根据胜利失败,展示不同的背景图片: if (victory) { gameResultImgOpp.sprite = this.failedImg; gameResultImgSelf.sprite = this.victoryImg; } else { gameResultImgOpp.sprite = this.victoryImg; gameResultImgSelf.sprite = this.failedImg; } if (!HUD.GameUI.instanceExists) { return; } if (HUD.GameUI.instance.state == HUD.GameUI.State.Building) { HUD.GameUI.instance.CancelGhostPlacement(); } HUD.GameUI.instance.GameOver(); } /// /// Occurs when the level is sucessfully completed /// protected void Victory() { OpenEndGameScreen(true); // if ((victorySound != null) && (audioSource != null)) // { // audioSource.PlayOneShot(victorySound); // } //background.color = winBackgroundColor; //first check if there are any more levels after this one //if (nextLevelButton == null || !GameManager.instanceExists) //{ // return; //} /* GameManager gm = GameManager.instance; LevelItem item = gm.GetLevelForCurrentScene(); LevelList list = gm.levelList; int levelCount = list.Count; int index = -1; for (int i = 0; i < levelCount; i++) { if (item == list[i]) { index = i; break; } } //if the level does not exist or this is the last level //hide the next level button if (index < 0 || index == levelCount - 1) { //nextLevelButton.enabled = false; //nextLevelButton.gameObject.SetActive(false); return; }*/ //nextLevelButton.enabled = true; //nextLevelButton.gameObject.SetActive(true); } /// /// Occurs when level is failed /// protected void Defeat() { OpenEndGameScreen( false );// levelFailedText); //if (nextLevelButton != null) //{ // nextLevelButton.enabled = false; // nextLevelButton.gameObject.SetActive(false); //} // if ((defeatSound != null) && (audioSource != null)) // { // audioSource.PlayOneShot(defeatSound); // } //background.color = loseBackgroundColor; } /// /// Safely unsubscribes from events. /// protected void OnDestroy() { SafelyUnsubscribe(); if (HUD.GameUI.instanceExists) { HUD.GameUI.instance.Unpause(); } } /// /// Ensure that events are unsubscribed from when necessary /// protected void SafelyUnsubscribe() { LazyLoad(); m_LevelManager.levelCompleted -= Victory; m_LevelManager.levelFailed -= Defeat; } /// /// Ensure is not null /// protected void LazyLoad() { if ((m_LevelManager == null) && LevelManager.instanceExists) { m_LevelManager = LevelManager.instance; } } /// /// Add up the health of all the Home Bases and return a score /// /// Final score protected int CalculateFinalScore() { int homeBaseCount = m_LevelManager.numberOfHomeBases; PlayerHomeBase[] homeBases = m_LevelManager.playerHomeBases; float totalRemainingHealth = 0f; float totalBaseHealth = 0f; for (int i = 0; i < homeBaseCount; i++) { Damageable config = homeBases[i].configuration; totalRemainingHealth += config.currentHealth; totalBaseHealth += config.maxHealth; } int score = CalculateScore(totalRemainingHealth, totalBaseHealth); return score; } /// /// Take the final remaining health of all bases and rates them /// /// the total remaining health of all home bases /// the total maximum health of all home bases /// 0 to 3 depending on how much health is remaining protected int CalculateScore(float remainingHealth, float maxHealth) { float normalizedHealth = remainingHealth / maxHealth; if (Mathf.Approximately(normalizedHealth, 1f)) { return 3; } if ((normalizedHealth <= 0.9f) && (normalizedHealth >= 0.5f)) { return 2; } if ((normalizedHealth < 0.5f) && (normalizedHealth > 0f)) { return 1; } return 0; } } }