/** * 玩家得分段位配置 * 依据玩家历史最高分(smc.data.score)划分段位:黄铜 -> 传说 */ /** 段位标识 */ export enum ScoreTier { BRONZE = "bronze", // 黄铜 SILVER = "silver", // 白银 GOLD = "gold", // 黄金 PLATINUM = "platinum", // 铂金 DIAMOND = "diamond", // 钻石 MASTER = "master", // 大师 LEGEND = "legend", // 传说 } /** 段位定义(按 minScore 升序排列) */ export interface ScoreRankInfo { /** 段位标识 */ tier: ScoreTier; /** 段位中文名 */ name: string; /** 进入该段位所需的最低分(含) */ minScore: number; /** 段位图标帧名(gui/ui6 图集内的 SpriteFrame 名,UI 层经 smc.uiconsAtlas 取帧) */ icon: string; } /** * 段位阈值表:score >= minScore 即达到对应段位 * 顺序必须保持 minScore 升序,供二分/逆序查找使用 */ export const ScoreRankList: ScoreRankInfo[] = [ { tier: ScoreTier.BRONZE, name: "黄铜", minScore: 0, icon: "League_1_Bronze" }, { tier: ScoreTier.SILVER, name: "白银", minScore: 2000, icon: "League_2_Silver" }, { tier: ScoreTier.GOLD, name: "黄金", minScore: 5000, icon: "League_3_Gold" }, { tier: ScoreTier.PLATINUM, name: "铂金", minScore: 10000, icon: "League_4_Platinum" }, { tier: ScoreTier.DIAMOND, name: "钻石", minScore: 20000, icon: "League_5_Diamond" }, { tier: ScoreTier.MASTER, name: "大师", minScore: 40000, icon: "League_6_Master" }, { tier: ScoreTier.LEGEND, name: "传说", minScore: 80000, icon: "League_7_Legendary" }, ]; /** * 根据分数获取当前段位 * @param score 玩家分数(通常传历史最高分 smc.data.score) * @returns 当前段位信息;score 为负时保底返回黄铜 */ export function getRankByScore(score: number): ScoreRankInfo { // 逆序遍历,命中第一个 minScore <= score 的段位即为当前段位 for (let i = ScoreRankList.length - 1; i >= 0; i--) { if (score >= ScoreRankList[i].minScore) { return ScoreRankList[i]; } } return ScoreRankList[0]; } /** * 根据分数获取下一段位目标 * @param score 玩家分数 * @returns 下一段位信息;已是传说(最高段位)时返回 null */ export function getNextRank(score: number): ScoreRankInfo | null { const current = getRankByScore(score); const idx = ScoreRankList.indexOf(current); return idx < ScoreRankList.length - 1 ? ScoreRankList[idx + 1] : null; } /** * 计算当前分数在当前段位内的进度 * @param score 玩家分数 * @returns 0~1 的进度值;已是最高段位时恒为 1 */ export function getRankProgress(score: number): number { const current = getRankByScore(score); const next = getNextRank(score); if (!next) return 1; const range = next.minScore - current.minScore; return range > 0 ? Math.min((score - current.minScore) / range, 1) : 1; }