const { ccclass, property } = cc._decorator; /** Reuses glyph slots authored in the prefab; no runtime node construction. */ @ccclass export default class CoinMadnessDigits extends cc.Component { @property([cc.SpriteFrame]) frames: cc.SpriteFrame[] = []; @property(cc.SpriteFrame) slashFrame: cc.SpriteFrame = null; @property height = 31; @property gap = 0; @property colonWidth = .36; private text = ''; setText(text: string) { if (this.text === text) return; if (text.length > this.node.children.length) { cc.warn('Coin Madness digit capacity exceeded', text); return; } this.text = text; const glyphs = text.split('').map(char => { // The countdown separator is intentional text, never a missing-image fallback. if (char === ':') return { char, frame: null, width: this.height * this.colonWidth }; const frame = char === '/' ? this.slashFrame : this.frames[Number(char)]; const rect = frame.getRect(); return { char, frame, width: this.height * rect.width / rect.height }; }); let x = -(glyphs.reduce((sum, glyph) => sum + glyph.width, 0) + this.gap * (glyphs.length - 1)) / 2; this.node.children.forEach((slot, i) => { slot.active = i < glyphs.length; if (!slot.active) return; const glyph = glyphs[i]; slot.x = x + glyph.width / 2; const image = slot.getChildByName('Image'); image.active = glyph.char !== ':'; if (glyph.char !== ':') { image.getComponent(cc.Sprite).spriteFrame = glyph.frame; image.setContentSize(glyph.width, this.height); } x += glyph.width + this.gap; }); } }