MatchMaster/assets/coin_madness/script/CoinMadnessDigits.ts

43 lines
2.2 KiB
TypeScript

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 = '';
private widthLimit = -1;
private renderedWidth = 0;
setText(text: string, maxWidth = 0): number {
if (this.text === text && this.widthLimit === maxWidth) return this.renderedWidth;
if (text.length > this.node.children.length) { cc.warn('Coin Madness digit capacity exceeded', text); return this.renderedWidth; }
this.text = text;
this.widthLimit = maxWidth;
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 };
});
// Bounded amounts need clear spacing, including outlines on the digit artwork.
const gap = maxWidth > 0 ? Math.max(2, this.gap) : this.gap;
const width = glyphs.reduce((sum, glyph) => sum + glyph.width, 0) + gap * Math.max(0, glyphs.length - 1);
const scale = maxWidth > 0 && width > maxWidth ? maxWidth / width : 1;
this.renderedWidth = width * scale;
let x = -this.renderedWidth / 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 * scale / 2;
const image = slot.getChildByName('Image');
image.active = glyph.char !== ':';
if (glyph.char !== ':') { image.getComponent(cc.Sprite).spriteFrame = glyph.frame; image.setContentSize(glyph.width * scale, this.height * scale); }
x += (glyph.width + gap) * scale;
});
return this.renderedWidth;
}
}