const { ccclass, property } = cc._decorator; type RewardType = "hammer" | "freeze" | "magic_wand" | "coin" | "infinite_health"; @ccclass export default class JungleOver extends cc.Component { @property(cc.BitmapFont) countFont: cc.BitmapFont = null; private confirming: boolean = false; private readonly displayOrder: RewardType[] = [ "hammer", "freeze", "magic_wand", "coin", "infinite_health", ]; onLoad() { const close = this.node.getChildByName("close"); if (close) { close.on(cc.Node.EventType.TOUCH_END, this.onClose, this); } } onDestroy() { const close = this.node && this.node.getChildByName("close"); if (close) { close.off(cc.Node.EventType.TOUCH_END, this.onClose, this); } } public init(pendingSettlement: any): boolean { const rewards = pendingSettlement && pendingSettlement.rewards; if (!rewards || !this.countFont) { return false; } const groups = this.displayOrder.map((type) => this.node.getChildByName(this.getNodeName(type))); if (groups.some((node) => !node)) { return false; } const slots = groups.map((node) => cc.v2(node.x, node.y)); let visibleIndex = 0; this.displayOrder.forEach((type, index) => { const group = groups[index]; const count = Math.max(0, Math.floor(Number(rewards[type]) || 0)); group.active = count > 0; if (count <= 0) { return; } group.setPosition(slots[visibleIndex++]); this.setCount(group.getChildByName("count"), this.formatCount(type, count)); }); return visibleIndex > 0; } public setConfirming(confirming: boolean): void { this.confirming = confirming; } private onClose(): void { if (this.confirming) { return; } this.confirming = true; this.node.emit("jungle-over-close"); } private setCount(target: cc.Node, text: string): void { if (!target) { return; } let label = target.getComponent(cc.Label); if (!label) { label = target.addComponent(cc.Label); } label.font = this.countFont; label.fontSize = 54; label.lineHeight = 54; label.horizontalAlign = cc.Label.HorizontalAlign.CENTER; label.verticalAlign = cc.Label.VerticalAlign.CENTER; label.string = text; target.setContentSize(Math.max(110, text.length * 54), 60); } private formatCount(type: RewardType, count: number): string { if (type === "infinite_health") { const totalMinutes = Math.max(1, Math.floor(count / 60)); const hours = Math.floor(totalMinutes / 60); const minutes = totalMinutes % 60; if (hours > 0 && minutes > 0) { return `${hours}小时${minutes}分钟`; } return hours > 0 ? `${hours}小时` : `${minutes}分钟`; } return type === "coin" ? count.toString() : `x${count}`; } private getNodeName(type: RewardType): string { switch (type) { case "freeze": return "ice"; case "magic_wand": return "magic"; case "infinite_health": return "tili"; default: return type; } } }