Newer
Older
rpg / packages / engine / src / render / fx / particlePresets.ts
import type { EmitterOptions } from '../Particles';
import { mergeEmitterOptions } from '../particleSim';

/**
 * Готовые наборы EmitterOptions для частых one-shot эффектов. Каждая фабрика —
 * детерминированные дефолты + переопределения вызывающего (mergeEmitterOptions):
 * `oneShot(10, sparkPreset(0xf2b45a, { seed }))`. Цвет — обязательный первый
 * аргумент там, где он определяет смысл эффекта (искры, угольки).
 */

/** Искры удара: быстрые разлетающиеся, тормозят, светятся (add-блендинг). */
export function sparkPreset(color: number, over?: Partial<EmitterOptions>): EmitterOptions {
    return mergeEmitterOptions({
        color,
        rate: 0,
        lifetime: [0.2, 0.45],
        radialSpeed: [70, 170],
        drag: 2.5,
        size: [1, 2],
        blend: 'add'
    }, over);
}

/** Дым/пепел: медленный подъём, рост и растворение, без блендинга. */
export function smokePreset(color: number, over?: Partial<EmitterOptions>): EmitterOptions {
    return mergeEmitterOptions({
        color,
        rate: 0,
        lifetime: [0.6, 1.2],
        velocity: { x: [-8, 8], y: [-24, -10] },
        acceleration: { y: 6 },
        size: [2, 4],
        scaleOverLife: 'grow'
    }, over);
}

/** Угольки/мотыльки: медленный дрейф вверх с синус-качанием, тёплый свет. */
export function emberPreset(color: number, over?: Partial<EmitterOptions>): EmitterOptions {
    return mergeEmitterOptions({
        color,
        rate: 0,
        lifetime: [1.0, 2.0],
        velocity: { x: [-10, 10], y: [-18, -6] },
        wobble: 6,
        size: 1,
        fadeIn: 0.3,
        blend: 'add'
    }, over);
}

/** Пыль от шага/приземления: короткая, низкая, быстро тормозит. */
export function dustPreset(color: number, over?: Partial<EmitterOptions>): EmitterOptions {
    return mergeEmitterOptions({
        color,
        rate: 0,
        lifetime: [0.25, 0.5],
        velocity: { x: [-14, 14], y: [-6, -2] },
        drag: 2,
        size: [1, 2]
    }, over);
}