import type { Updatable } from '../../core/Updatables';
import type { Vec2 } from '../../math/Vec2';
import { PixelText, type PixelTextOptions } from '../../ui/PixelText';
import { sampleFloat, type FxFloatSpec } from './fxSim';
/**
* Всплывающий текст: подъём + затухание (числа урона, тосты, подборы).
* Владеет своим PixelText: создаёт, тикает и уничтожает себя по завершении.
* Позиция задаётся при создании (at), update только смещает от неё.
*/
export class FxFloatText extends PixelText implements Updatable {
private t = 0;
private cancelled = false;
private readonly baseX: number;
private readonly baseY: number;
constructor(
text: string,
at: Vec2,
private readonly spec: FxFloatSpec,
style?: Partial<PixelTextOptions>
) {
super({ text, size: 11, ...style });
this.anchor.set(0.5);
this.baseX = at.x;
this.baseY = at.y;
this.position.set(at.x, at.y);
}
/** Досрочно погасить (например, новый тост вытесняет старый). */
cancel(): void {
if (this.cancelled) return;
this.cancelled = true;
this.destroy({ children: true });
}
/** true, когда текст доиграл (или погашен). */
get done(): boolean {
return this.cancelled || this.t >= this.spec.duration - 1e-6;
}
update(dt: number): void {
if (this.destroyed) return;
this.t += dt;
const s = sampleFloat(this.t, this.spec);
this.x = this.baseX + s.x;
this.y = this.baseY + s.y;
this.alpha = s.alpha;
this.scale.set(s.scale);
if (this.done) this.destroy({ children: true });
}
}