添加场景、对应场景代码
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// 单条玩家得分记录。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class PlayerScore
|
||||
{
|
||||
public int score;
|
||||
public string playerName;
|
||||
|
||||
public PlayerScore(int score, string playerName)
|
||||
{
|
||||
this.score = score;
|
||||
this.playerName = playerName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 可序列化的玩家得分列表(用于 JSON 存档)。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class PlayerScoreData
|
||||
{
|
||||
public List<PlayerScore> list = new List<PlayerScore>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 得分管理器(持久单例)。
|
||||
/// 维护当前局得分,通过事件通知 UI,并管理 Top-10 排行榜存档。
|
||||
/// </summary>
|
||||
public class ScoreManager : PersistentSingleton<ScoreManager>
|
||||
{
|
||||
const int LEADERBOARD_SIZE = 10;
|
||||
const string SAVE_FILE = "leaderboard.json";
|
||||
|
||||
// 当前局得分
|
||||
int currentScore = 0;
|
||||
|
||||
// 当得分变化时触发,参数为最新得分(动画过程中的中间值也会触发)
|
||||
public static event Action<int> onScoreChanged;
|
||||
// 当得分完成最终增加时触发,参数为最终得分
|
||||
public static event Action<int> onScoreSettled;
|
||||
|
||||
/// <summary>当前得分(只读)。</summary>
|
||||
public int CurrentScore => currentScore;
|
||||
|
||||
/// <summary>默认玩家名,可在 Inspector 设置。</summary>
|
||||
[SerializeField] string defaultPlayerName = "Player";
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
if (Instance != this) return;
|
||||
currentScore = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加得分(带数字滚动动画)。
|
||||
/// </summary>
|
||||
public void AddScore(int amount)
|
||||
{
|
||||
if (amount <= 0) return;
|
||||
StartCoroutine(ScoreCountUpCoroutine(currentScore, currentScore + amount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 直接设置得分(无动画)。
|
||||
/// </summary>
|
||||
public void SetScore(int value)
|
||||
{
|
||||
currentScore = Mathf.Max(0, value);
|
||||
onScoreChanged?.Invoke(currentScore);
|
||||
onScoreSettled?.Invoke(currentScore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置当前局得分。
|
||||
/// </summary>
|
||||
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 排行榜
|
||||
/// <summary>
|
||||
/// 当前得分是否能进入排行榜 Top-10。
|
||||
/// </summary>
|
||||
public bool HasNewHighScore
|
||||
{
|
||||
get
|
||||
{
|
||||
var data = LoadPlayerScoreData();
|
||||
if (data.list.Count < LEADERBOARD_SIZE)
|
||||
return true;
|
||||
return currentScore > data.list[LEADERBOARD_SIZE - 1].score;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将当前得分以指定名字保存到排行榜。
|
||||
/// 排行榜按分数降序排列,只保留 Top-10。
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取排行榜数据。
|
||||
/// </summary>
|
||||
public PlayerScoreData LoadPlayerScoreData()
|
||||
{
|
||||
if (SaveSystem.SaveFileExists(SAVE_FILE))
|
||||
return SaveSystem.Load<PlayerScoreData>(SAVE_FILE);
|
||||
return new PlayerScoreData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空排行榜存档。
|
||||
/// </summary>
|
||||
public void ClearLeaderboard()
|
||||
{
|
||||
SaveSystem.DeleteSaveFile(SAVE_FILE);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user