refactor(score): 重构积分段位与生涯积分逻辑

1. 更新段位配置阈值,改为按局均20分估算的累计分标准
2. 修改生涯积分逻辑,改为累计正贡献分且不会回退
3. 优化结算页积分展示和涨幅提示逻辑,新增升段提示
4. 完善文档注释,修正积分规则描述
This commit is contained in:
pan
2026-09-11 16:30:16 +08:00
parent bde6825aa0
commit 6afb8af05e
2 changed files with 39 additions and 38 deletions

View File

@@ -158,9 +158,9 @@ export class VictoryComp extends CCComp {
/** 动画期间实时显示的分数(tween 驱动) */
private _displayScore: number = 0;
/** 滚动前的历史最高分(动画起始值) */
/** 滚动前的生涯累计分(动画起始值) */
private _prevBestScore: number = 0;
/** 本局总分(动画结束值) */
/** 滚动后的生涯累计分(动画结束值) */
private _finalScore: number = 0;
/** 滚动起始段位(用于检测跨段) */
private _startRank: ScoreRankInfo = null!;
@@ -313,15 +313,14 @@ export class VictoryComp extends CCComp {
}
/**
* 计算单局总分并更新到 smc.vmdata.scores.score。
* 同时刷新 smc.data.score 历史最高分。
* 计算本局得分并累加到生涯总分(smc.data.score 为累计分,驱动段位)。
*
* 积分规则:
* - 胜利 +10 分,全队存活 +5 分;失败 -10 分
* - 暴击/闪避/击晕/冰冻每次 +1 分,单项封顶 5 分(不分胜负均计入)
* - 单局:胜利 +10(全队存活再 +5)/ 失败 -10;暴击/闪避/击晕/冰冻每次 +1、单项封顶 5
* - 累计:生涯分 += max(0, 本局分),负分局不回退(不掉段),累计下限钳 0
*
* @param isVictory 是否胜利
* @param allAlive 是否全英雄存活
* @param allAlive 是否全队存活
*/
private calculateTotalScore(isVictory: boolean, allAlive: boolean) {
const s = smc.vmdata.scores;
@@ -343,35 +342,32 @@ export class VictoryComp extends CCComp {
const stunPts = Math.min(5, s.stun_count);
const freezePts = Math.min(5, s.freeze_count);
// 存储当前局分数(失败局可为负,但总分下限钳 0)
s.score = Math.max(0, Math.floor(base + critPts + dodgePts + stunPts + freezePts));
// 本局得分:失败局可为负(结算页如实展示)
s.score = Math.floor(base + critPts + dodgePts + stunPts + freezePts);
// 亮点成就判定:仅作结算页亮点标签展示,不计入总分
s.achieved_highlights = this.getAchievedHighlights(s);
// 记录滚动前的历史最高分(动画起始值)
// 累计生涯分:正贡献累加、负分不回退(声望式不掉段),下限钳 0
this._prevBestScore = smc.data.score;
this._finalScore = s.score;
const gain = Math.max(0, s.score);
smc.data.score = Math.max(0, this._prevBestScore + gain);
this._finalScore = smc.data.score;
// 判定是否打破历史最高分记录
let isNewRecord = false;
if (s.score > smc.data.score) {
smc.data.score = s.score;
isNewRecord = true;
// 更新云端/本地存储,保存新记录
if (typeof smc.updateCloudData === "function") {
smc.updateCloudData();
}
// 持久化生涯分(云端/本地同步)
if (typeof smc.updateCloudData === "function") {
smc.updateCloudData();
}
// 借用 scores 对象传递新记录标记,供 UI 渲染使用
(s as any).isNewRecord = isNewRecord;
// 借用 scores 对象传递标记:本局有正贡献(供涨幅标签展示)
(s as any).isNewRecord = gain > 0;
mLogger.log(this.debugMode, 'VictoryComp', `[VictoryComp] 结算总分: ${s.score}`, {
mLogger.log(this.debugMode, 'VictoryComp', `[VictoryComp] 本局得分: ${s.score}`, {
base,
critPts, dodgePts, stunPts, freezePts,
isNewRecord: isNewRecord,
prevBest: this._prevBestScore
gain,
careerTotal: this._finalScore,
prevTotal: this._prevBestScore
});
}
@@ -510,21 +506,23 @@ export class VictoryComp extends CCComp {
}
/**
* 滚动定格后显示 +N 涨幅标签(仅破纪录时)
* 滚动定格后显示 +N 涨幅标签(本局有正贡献时;跨段位时附加升段文案)
*/
private showGainLabel() {
if (!this.gain_label) return;
const s = smc.vmdata.scores;
const isNewRecord = (s as any).isNewRecord === true;
const hasGain = (s as any).isNewRecord === true;
const gain = this._finalScore - this._prevBestScore;
if (!isNewRecord || gain <= 0) {
if (!hasGain || gain <= 0) {
this.gain_label.node.active = false;
return;
}
this.gain_label.string = `+${gain} 新纪录!`;
// 跨段位判定:滚动前后段位不一致即为升段(累计分只涨不跌,不存在降段)
const rankUp = getRankByScore(this._finalScore).tier !== getRankByScore(this._prevBestScore).tier;
this.gain_label.string = rankUp ? `+${gain} 升段!` : `+${gain}`;
this.gain_label.node.active = true;
// 浮现动效:从 0 缩放淡入