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

Эмиттеры частиц — один из самых эффектных инструментов для визуального оживления игры. С их помощью можно легко создавать огонь, дым, звёзды, магические следы или, как в этом примере, падающий каскад иконок. В этой статье мы разберем, как работает эмиттер с пошаговым (stepped) распределением и эффектом возврата (yoyo), что позволяет создавать сложные паттерны движения без написания громоздкого кода. Это полезно для создания повторяющихся анимаций, например, фонтанов или циклически движущихся цепочек частиц.

Версия 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/tweens/sky.png');
        this.load.atlas('match3', 'assets/atlas/match3.png', 'assets/atlas/match3.json');
    }

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

        this.add.particles(0, 100, 'match3', {
            x: { start: 100, end: 640, steps: 16, yoyo: true },
            frame: 'Match3_Icon_19',
            lifespan: 3000,
            gravityY: 200,
            scale: 0.15
        });
    }
}

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

const game = new Phaser.Game(config);

Разбираем структуру примера

Пример состоит из стандартной для Phaser 3 структуры: класс сцены Example, унаследованный от Phaser.Scene, и конфигурация игры. В сцене реализованы два ключевых метода жизненного цикла: preload для загрузки ресурсов и create для их размещения на сцене и настройки логики.

class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('bg', 'assets/tweens/sky.png');
        this.load.atlas('match3', 'assets/atlas/match3.png', 'assets/atlas/match3.json');
    }

    create ()
    {
        // Создание фона и эмиттера будет здесь
    }
}

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

const game = new Phaser.Game(config);

Загрузка ресурсов: изображение и атлас

В методе preload мы загружаем два ресурса. Сначала устанавливаем базовый URL для загрузки, чтобы не указывать полный путь к каждому файлу. Затем загружаем фоновое изображение 'bg'.

Ключевой ресурс для эмиттера — это атлас 'match3'. Атлас — это изображение, содержащее множество отдельных спрайтов (кадров), и JSON-файл, описывающий их координаты. Использование атласа эффективно для производительности. В нашем случае атлас содержит иконки для игры типа "три в ряд".

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bg', 'assets/tweens/sky.png');
this.load.atlas('match3', 'assets/atlas/match3.png', 'assets/atlas/match3.json');

Создание эмиттера частиц

В методе create сначала добавляем фоновое изображение. Затем создаем эмиттер частиц с помощью this.add.particles(). Первые два аргумента (0, 100) — это начальные координаты `xиyдля эмиттера. Третий аргумент'match3'` — ключ текстуры (атласа). Четвертый аргумент — объект конфигурации эмиттера.

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

this.add.particles(0, 100, 'match3', {
    x: { start: 100, end: 640, steps: 16, yoyo: true },
    frame: 'Match3_Icon_19',
    lifespan: 3000,
    gravityY: 200,
    scale: 0.15
});

Конфигурация — это сердце примера. Давайте разберем её свойства.

Секрет движения: stepped и yoyo

Самое интересное свойство — `x. Оно задано не простым числом, а объектом с конфигурацией, которая определяет, как будет меняться координатаx` у каждой новой создаваемой частицы.

* start: 100 — начальное значение `x` для первой частицы. * end: 640 — конечное значение `x`. * steps: 16 — количество шагов (или позиций) между start и end. Эмиттер создаст 16 частиц, каждая из которых будет появляться в новой точке по оси X, равномерно распределенной между 100 и 640. * yoyo: true — включает эффект "йо-йо". Это означает, что после достижения end (640), система начнет двигаться в обратном направлении — от end к start. Таким образом, общее количество уникальных позиций для частиц удваивается (32), создавая паттерн "туда-обратно".

x: { start: 100, end: 640, steps: 16, yoyo: true }

Остальные свойства конфигурации: * frame: 'Match3_Icon_19' — указывает, какой конкретный кадр из атласа 'match3' использовать для всех частиц. * lifespan: 3000 — время жизни частицы в миллисекундах (3 секунды). * gravityY: 200 — сила гравитации по оси Y. Частицы будут падать вниз с ускорением. * scale: 0.15 — масштаб частиц (15% от исходного размера кадра).

Итог работы кода

В результате мы получаем следующий визуальный эффект: 1. Эмиттер, расположенный в координатах (0, 100), начинает испускать частицы. 2. Первая частица появляется в точке X=100, следующая — на следующей равномерно распределенной позиции (например, ~133.75), и так далее, пока не будет достигнута позиция X=640 (16-я частица). 3. Благодаря yoyo: true, 17-я частица появится на позиции, предшествующей 640, и процесс пойдет в обратном направлении к X=100, создавая цикл. 4. Все частицы имеют форму иконки Match3_Icon_19, они маленькие (scale: 0.15), живут 3 секунды и падают вниз под действием гравитации (gravityY: 200).

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

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

Конфигурация эмиттера с steps и yoyo — мощный и лаконичный способ создавать сложные, циклические паттерны движения для частиц без необходимости управлять каждой частицей вручную. Для экспериментов попробуйте изменить количество steps, чтобы частицы появлялись реже или чаще. Добавьте свойство frequency в конфигурацию эмиттера, чтобы управлять интервалом между испусканием частиц. Поиграйте с другими свойствами, такими как angle или speedY, чтобы создать эффект разлетающегося фейерверка или вращающегося кольца частиц.