using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Architecture.Core;
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();
}
///
/// 得分管理器(持久单例)。
/// 维护当前局得分,通过 SO 事件通道通知 UI,并管理 Top-10 排行榜存档。
///
public class ScoreManager : PersistentSingleton
{
const int LEADERBOARD_SIZE = 10;
const string SAVE_FILE = "leaderboard.json";
// 当前局得分
int currentScore = 0;
[Header("SO 事件通道(替代 static onScoreChanged / onScoreSettled 事件,Inspector 拖入对应资产)")]
[SerializeField] private IntEvent scoreChangedEvent;
[SerializeField] private IntEvent scoreSettledEvent;
/// 当前得分(只读)。
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);
scoreChangedEvent?.Raise(currentScore);
scoreSettledEvent?.Raise(currentScore);
}
///
/// 重置当前局得分。
///
public void ResetScore()
{
currentScore = 0;
scoreChangedEvent?.Raise(0);
scoreSettledEvent?.Raise(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));
scoreChangedEvent?.Raise(display);
yield return null;
}
scoreChangedEvent?.Raise(to);
scoreSettledEvent?.Raise(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
}
}