Newer
Older
rpg / packages / engine / src / render / fx / FxTrail.ts
import { Container } from 'pixi.js';
import type { Updatable } from '../../core/Updatables';
import { ParticleEmitter, type EmitterOptions } from '../Particles';

/**
 * Шлейф за движущейся вьюхой (снаряды, бегущий герой): эмиттер тянется за
 * якорем каждый тик, пока не остановлен. stop() выключает спавн; когда
 * последняя частица умрёт, эмиттер уничтожается и эффект заканчивается.
 */
export class FxTrail implements Updatable {
    /** Готовый эмиттер (можно дотюнить setOptions — цвет, rate, lifetime). */
    readonly view: ParticleEmitter;
    private stopped = false;
    private finished = false;

    constructor(
        private readonly anchor: Container,
        opts: EmitterOptions
    ) {
        this.view = new ParticleEmitter({
            ...opts,
            rate: opts.rate ?? 24,
            lifetime: opts.lifetime ?? [0.3, 0.6]
        });
        this.view.position.set(anchor.x, anchor.y);
    }

    /** Перестать испускать (снаряд погас/умер): хвост самораспадается. */
    stop(): void {
        this.stopped = true;
        this.view.setOptions({ rate: 0 });
    }

    get destroyed(): boolean {
        return this.finished || this.anchor.destroyed;
    }

    update(dt: number): void {
        if (this.finished) return;
        if (!this.stopped) this.view.position.set(this.anchor.x, this.anchor.y);
        this.view.update(dt);
        if (this.stopped && this.view.count === 0) {
            this.view.destroy({ children: true });
            this.finished = true;
        }
    }
}