using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace GameFramework { /// /// 单条玩家得分记录。 /// [Serializable] public class PlayerScore { public int score; public string playerName; public PlayerScore(int score, string playerName) { this.score = score; this.playerName = playerName; } } /// /// 可序列化的玩家得分列表(用于 JSON 存档)。 /// [Serializable] public class PlayerScoreData { public List list = new List(); } /// /// 得分管理器(持久单例)。 /// 维护当前局得分,通过事件通知 UI,并管理 Top-10 排行榜存档。 /// public class ScoreManager : PersistentSingleton { const int LEADERBOARD_SIZE = 10; const string SAVE_FILE = "leaderboard.json"; // 当前局得分 int currentScore = 0; // 当得分变化时触发,参数为最新得分(动画过程中的中间值也会触发) public static event Action onScoreChanged; // 当得分完成最终增加时触发,参数为最终得分 public static event Action onScoreSettled; /// 当前得分(只读)。 public int CurrentScore => currentScore; /// 默认玩家名,可在 Inspector 设置。 [SerializeField] string defaultPlayerName = "Player"; protected override void Awake() { base.Awake(); if (Instance != this) return; currentScore = 0; } /// /// 增加得分(带数字滚动动画)。 /// public void AddScore(int amount) { if (amount <= 0) return; StartCoroutine(ScoreCountUpCoroutine(currentScore, currentScore + amount)); } /// /// 直接设置得分(无动画)。 /// public void SetScore(int value) { currentScore = Mathf.Max(0, value); onScoreChanged?.Invoke(currentScore); onScoreSettled?.Invoke(currentScore); } /// /// 重置当前局得分。 /// public void ResetScore() { currentScore = 0; onScoreChanged?.Invoke(0); onScoreSettled?.Invoke(0); } IEnumerator ScoreCountUpCoroutine(int from, int to) { currentScore = to; float duration = 0.5f; float elapsed = 0f; while (elapsed < duration) { elapsed += Time.unscaledDeltaTime; float t = Mathf.Clamp01(elapsed / duration); int display = Mathf.RoundToInt(Mathf.Lerp(from, to, t)); onScoreChanged?.Invoke(display); yield return null; } onScoreChanged?.Invoke(to); onScoreSettled?.Invoke(to); } #region 排行榜 /// /// 当前得分是否能进入排行榜 Top-10。 /// public bool HasNewHighScore { get { var data = LoadPlayerScoreData(); if (data.list.Count < LEADERBOARD_SIZE) return true; return currentScore > data.list[LEADERBOARD_SIZE - 1].score; } } /// /// 将当前得分以指定名字保存到排行榜。 /// 排行榜按分数降序排列,只保留 Top-10。 /// public void SavePlayerScore(string playerName) { if (string.IsNullOrEmpty(playerName)) playerName = defaultPlayerName; var data = LoadPlayerScoreData(); data.list.Add(new PlayerScore(currentScore, playerName)); data.list.Sort((a, b) => b.score.CompareTo(a.score)); if (data.list.Count > LEADERBOARD_SIZE) data.list.RemoveRange(LEADERBOARD_SIZE, data.list.Count - LEADERBOARD_SIZE); SaveSystem.Save(SAVE_FILE, data); } /// /// 读取排行榜数据。 /// public PlayerScoreData LoadPlayerScoreData() { if (SaveSystem.SaveFileExists(SAVE_FILE)) return SaveSystem.Load(SAVE_FILE); return new PlayerScoreData(); } /// /// 清空排行榜存档。 /// public void ClearLeaderboard() { SaveSystem.DeleteSaveFile(SAVE_FILE); } #endregion } }