О чем этот пример

Создание динамичных визуальных эффектов — ключевая часть геймдева. В Phaser 3 частицы (Particle Emitter) позволяют легко реализовать дождь, огонь, магию и другие системы. Однако стандартный эмиттер непрерывно испускает частицы. В этой статье мы разберем, как с помощью свойства `hold` сделать так, чтобы частицы появлялись, замирали на месте на заданное время и лишь затем начинали двигаться по законам физики. Этот прием отлично подходит для создания эффекта "взведенной" катапульты, застывших во времени сфер или подготовки каскадного падения объектов.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('bg', 'assets/skies/gradient26.png');
        this.load.image('ball', 'assets/demoscene/green_ball.png');
        this.load.image('platform', 'assets/particles/platform.png');
    }

    create ()
    {
        this.add.image(400, 300, 'bg');

        this.add.image(-100, 500, 'platform').setOrigin(0, 0);
        this.add.image(412, 500, 'platform').setOrigin(0, 0);

        this.add.particles(0, -32, 'ball', {
            x: { min: 0, max: 800 },
            gravityY: 200,
            lifespan: 2235,
            hold: 2000,
            sortProperty: 'lifeT',
            sortOrderAsc: true
        });
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#000',
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Суть свойства `hold`

Свойство hold в конфигурации эмиттера частиц — это время в миллисекундах, в течение которого только что созданная частица будет находиться в состоянии покоя. Она появится на экране с заданными начальными координатами, но не будет подвержена силам (таким как гравитация gravityY) и не начнет "стареть" (уменьшаться lifespan).

По истечении времени hold частица "оживает": к ней применяется физика, и запускается отсчет ее времени жизни. Это позволяет создавать сложные, многоступенчатые эффекты и контролировать момент начала движения.

Разбор примера: Застывший дождь из шаров

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

this.add.particles(0, -32, 'ball', {
    x: { min: 0, max: 800 },
    gravityY: 200,
    lifespan: 2235,
    hold: 2000,
    sortProperty: 'lifeT',
    sortOrderAsc: true
});

Здесь ключевые параметры: - `x: Частицы будут появляться случайным образом по всей ширине экрана (от 0 до 800 пикселей). Их начальная координатаy` фиксирована и равна -32 (чуть выше верхней границы окна). - gravityY: Сила гравитации, которая начнет действовать на частицу только после фазы hold. - lifespan: Общее время жизни частицы (2235 мс), которое также отсчитывается после окончания hold. - hold: Время "заморозки" — 2000 миллисекунд (2 секунды).

Как работает жизненный цикл частицы

Благодаря hold жизненный цикл каждой частицы делится на две четкие фазы.

**Фаза 1: Ожидание (0-2000 мс)** Частица появляется вверху экрана и неподвижно висит в воздухе. Гравитация и отсчет lifespan приостановлены. За первые 2 секунды эмиттер успевает создать множество таких "замерзших" шаров, равномерно заполняя пространство над платформами.

**Фаза 2: Падение (2000-4235 мс)** Ровно через 2000 мс после создания частица "просыпается". С этого момента: 1. На нее начинает действовать gravityY: 200, и шар устремляется вниз. 2. Запускается таймер lifespan. Через 2235 мс после начала этой фазы частица автоматически уничтожится.

Эффект: сначала на экране формируется "облако" из статичных зеленых шаров, а затем они все одновременно начинают падать каскадом.

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

В конфиге также присутствуют параметры sortProperty и sortOrderAsc. Они управляют порядком отрисовки (рендеринга) частиц.

sortProperty: 'lifeT',
sortOrderAsc: true

lifeT — это внутреннее свойство частицы, представляющее ее оставшееся время жизни. При sortOrderAsc: true частицы с меньшим оставшимся временем жизни (т.е. те, что "старше") будут отрисованы первыми, а более новые — поверх них.

В нашем примере, так как все частицы начинают жить одновременно после hold, сортировка по lifeT обеспечивает стабильный порядок отрисовки, предотвращая мерцание и визуальные артефакты, когда шары перекрывают друг друга во время падения.

Практическое применение и вариации

Свойство hold открывает путь к нестандартным игровым механикам и эффектам.

**Идеи для использования:** 1. **Подготовка атаки:** Вражеская башня "заряжается" (частицы копятся), а затем выпускает залп. 2. **Эффект замедления времени:** Активация способности замораживает все летящие снаряды (hold: 3000), а после отмены способности они продолжают полет. 3. **Создание сложных форм:** Можно расположить эмиттер так, чтобы частицы образовали статичную надпись или логотип, а затем "рассыпались".

**Пример: Эмиттер с наклонным разбросом**

this.add.particles(400, 300, 'spark', {
    speed: { min: 100, max: 200 },
    angle: { min: 0, max: 180 },
    lifespan: 1500,
    hold: 1000,
    scale: { start: 1, end: 0 },
    emitting: false // Выпускаем одну порцию
});
emitter.explode(50); // Создаем 50 частиц сразу

В этом коде 50 искр появятся в форме полукруга, застынут на 1 секунду, а затем разлетятся с разной скоростью, постепенно исчезая.

Что попробовать дальше

Свойство hold в эмиттере частиц Phaser 3 — это мощный инструмент для разделения момента появления объекта и начала его физической симуляции. Оно добавляет контролируемую задержку, которая полезна для создания драматических пауз, эффектов накопления и сложной хореографии движения множества объектов. **Экспериментируйте:** Попробуйте комбинировать hold с другими свойствами, такими как delay (задержка между испусканием частиц) или frequency. Измените пример, добавив свойство onHold (если оно доступно в вашей версии Phaser) для вызова функции в момент "пробуждения" каждой частицы. Это может стать основой для интерактивных головоломок или зрелищных босс-файтов.