import * as Phaser from "phaser"; import { DigitRenderer } from "./DigitRenderer"; /** * 进度百分比显示组件(LED / 七段数码管风格)。 * 显示一个3位数字后跟百分号(如 "42%")。 */ export class ProgressDisplay { private scene: Phaser.Scene; private container: Phaser.GameObjects.Container; private digitGraphics: Phaser.GameObjects.Graphics[] = []; private digitWidth: number; private digitHeight: number; private digitSpacing: number; private percentWidth: number; private displayWidth: number; private anchorLeftX: number; constructor( scene: Phaser.Scene, parent: Phaser.GameObjects.Container, options: { xLeft: number; y: number; digitWidth: number; digitHeight: number; digitSpacing: number; percentWidth: number; }, ) { this.scene = scene; this.digitWidth = options.digitWidth; this.digitHeight = options.digitHeight; this.digitSpacing = options.digitSpacing; this.percentWidth = options.percentWidth; this.anchorLeftX = options.xLeft; // 3位数字 + 百分号 const totalWidth = this.digitWidth * 3 + this.percentWidth + this.digitSpacing * 3; this.displayWidth = totalWidth; this.container = scene.add.container( options.xLeft + totalWidth / 2, options.y, ); this.container.setSize(totalWidth, this.digitHeight); parent.add(this.container); let offsetX = -totalWidth / 2; // 3个数字槽位 for (let i = 0; i < 3; i++) { const g = scene.add.graphics(); g.setPosition(offsetX + this.digitWidth / 2, 0); offsetX += this.digitWidth; offsetX += this.digitSpacing; this.digitGraphics.push(g); this.container.add(g); } // 百分号 const percentG = scene.add.graphics(); percentG.setPosition(offsetX + this.percentWidth / 2, 0); this.digitGraphics.push(percentG); this.container.add(percentG); } /** * 更新容器位置,使第一个可见数字与图标对齐。 * 前导空白数字会将容器向左偏移。 * @param percent 百分比值 */ private updatePosition(percent: number): void { let leadingBlanks = 0; if (percent < 100) { leadingBlanks += 1; } if (percent < 10) { leadingBlanks += 1; } const blankWidth = leadingBlanks * (this.digitWidth + this.digitSpacing); this.container.x = this.anchorLeftX - blankWidth + this.displayWidth / 2; } /** * 根据已消除/总数更新进度显示。 * @param removed 已消除的路径数 * @param total 总路径数 */ public updateProgress(removed: number, total: number): void { if (!this.container || this.digitGraphics.length < 4) { return; } let percent = 0; if (total > 0) { percent = Math.floor((removed / total) * 100); } percent = Math.max(0, Math.min(100, percent)); this.updatePosition(percent); const color = 0x50536b; const digitWidth = this.digitWidth; const digitHeight = this.digitHeight; const hundreds = percent >= 100 ? 1 : -1; const tens = percent >= 10 ? Math.floor((percent % 100) / 10) : -1; const ones = percent % 10; // 百位 DigitRenderer.drawDigit( this.digitGraphics[0], hundreds, color, digitWidth, digitHeight, ); // 十位 DigitRenderer.drawDigit( this.digitGraphics[1], tens, color, digitWidth, digitHeight, ); // 个位 DigitRenderer.drawDigit( this.digitGraphics[2], ones, color, digitWidth, digitHeight, ); // 百分号 DigitRenderer.drawPercentSign(this.digitGraphics[3], color, digitHeight); } }