Ручное управление частицами

В PixiJS система частиц может работать как через готовые библиотеки (например, pixi-particles), так и с использованием собственных контейнеров и спрайтов. Ручное управление частицами подразумевает создание, обновление и удаление частиц без автоматической генерации системы. Такой подход обеспечивает полный контроль над поведением, визуальными эффектами и производительностью.


Создание контейнера для частиц

Частицы удобно хранить в отдельном контейнере:

const particleContainer = new PIXI.Container();
app.stage.addChild(particleContainer);

Использование PIXI.Container позволяет эффективно управлять большим количеством спрайтов и минимизировать перерасход ресурсов за счёт объединения рендеринга объектов.


Создание и настройка отдельных частиц

Частица представляет собой спрайт с дополнительными свойствами: скорость, направление, время жизни, размер и прозрачность.

function createParticle(texture, x, y) {
    const particle = new PIXI.Sprite(texture);
    particle.x = x;
    particle.y = y;
    particle.vx = (Math.random() - 0.5) * 5; // горизонтальная скорость
    particle.vy = (Math.random() - 0.5) * 5; // вертикальная скорость
    particle.life = 100 + Math.random() * 50; // продолжительность жизни в кадрах
    particle.alpha = 1; // начальная прозрачность
    particle.scale.set(0.5 + Math.random() * 0.5); // случайный масштаб
    return particle;
}

Ключевые моменты:

  • vx, vy определяют направление и скорость движения.
  • life контролирует продолжительность отображения частицы.
  • scale позволяет создавать разнообразие визуальных эффектов.
  • alpha используется для плавного исчезновения.

Обновление частиц

Ручное управление требует обновления каждой частицы в цикле ticker:

app.ticker.add(() => {
    for (let i = particleContainer.children.length - 1; i >= 0; i--) {
        const p = particleContainer.children[i];
        p.x += p.vx;
        p.y += p.vy;
        p.life -= 1;
        p.alpha = p.life / 150; // плавное исчезновение

        if (p.life <= 0) {
            particleContainer.removeChild(p);
        }
    }
});

Особенности подхода:

  • Проход по массиву children ведётся в обратном порядке, чтобы безопасно удалять объекты без нарушения индексов.
  • Изменение прозрачности alpha создаёт эффект исчезания.
  • Можно добавить гравитацию, ускорение или вращение, расширяя свойства vx, vy и rotation.

Добавление гравитации и ускорения

Для более реалистичного движения частиц можно использовать ускорение:

p.ay = 0.2; // вертикальное ускорение (гравитация)

app.ticker.add(() => {
    for (let i = particleContainer.children.length - 1; i >= 0; i--) {
        const p = particleContainer.children[i];
        p.vy += p.ay;
        p.x += p.vx;
        p.y += p.vy;
        p.life -= 1;
        p.alpha = p.life / 150;

        if (p.life <= 0) {
            particleContainer.removeChild(p);
        }
    }
});

Добавление ускорения делает движение более естественным, особенно для эффекта падающих частиц или огненных вспышек.


Использование текстур и анимаций

Для увеличения разнообразия визуальных эффектов можно использовать разные текстуры или анимированные спрайты:

const textures = [
    PIXI.Texture.from('particle1.png'),
    PIXI.Texture.from('particle2.png'),
    PIXI.Texture.from('particle3.png')
];

function createRandomParticle(x, y) {
    const texture = textures[Math.floor(Math.random() * textures.length)];
    return createParticle(texture, x, y);
}

Анимация спрайтов с последовательностью текстур может имитировать дым, огонь или магические эффекты. Для этого применяют PIXI.AnimatedSprite.


Оптимизация производительности

При большом количестве частиц важно учитывать производительность:

  • Использовать PIXI.ParticleContainer вместо обычного PIXI.Container. Это существенно ускоряет рендеринг, но ограничивает возможности (нет поддержки некоторых свойств, например, фильтров).
  • Пакетное создание и удаление частиц вместо создания каждой частицы в реальном времени.
  • Ограничение количества активных частиц с удалением старых по таймеру или при выходе за пределы сцены.
const particleContainerOptimized = new PIXI.ParticleContainer(1000, {
    scale: true,
    position: true,
    rotation: true,
    alpha: true
});
app.stage.addChild(particleContainerOptimized);

Взаимодействие с событиями

Частицы могут реагировать на события пользователя: мышь, касания или физические взаимодействия.

app.renderer.plugins.interaction.on('pointermove', (event) => {
    const pos = event.data.global;
    const particle = createRandomParticle(pos.x, pos.y);
    particleContainer.addChild(particle);
});

Такой подход позволяет создавать интерактивные эффекты, например, след курсора из частиц или реакцию на клики.


Управление цветом и прозрачностью

Цветовые эффекты добавляют глубину визуализации. Для этого используют tint и анимируют alpha:

p.tint = Math.random() * 0xFFFFFF;
p.alpha = 1;

app.ticker.add(() => {
    for (const p of particleContainer.children) {
        p.alpha -= 0.01; // постепенное исчезновение
        if (p.alpha <= 0) particleContainer.removeChild(p);
    }
});

Возможна комбинация с изменением размера (scale) и вращением (rotation) для более динамичных эффектов.


Смешение эффектов

Ручное управление частицами открывает возможность создавать сложные эффекты через комбинацию:

  • Векторное движение с ускорением.
  • Цветовые переходы.
  • Анимацию текстур.
  • Взаимодействие с мышью или объектами сцены.

Используя эти техники совместно, можно строить системы частиц любого уровня сложности без внешних библиотек, сохраняя полный контроль над поведением и производительностью.