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

При создании множества игровых объектов часто требуется изменять их свойства не случайным образом, а по заданному алгоритму. Например, сделать так, чтобы спрайты в группе постепенно становились прозрачными от первого к последнему. Вручную перебирать все элементы и рассчитывать для каждого значение — долго и неудобно. В Phaser для таких задач существует мощный набор методов `Phaser.Actions`. В этой статье мы разберем один из них — `Spread`, который позволяет распределить значение определенного свойства для всех детей группы между двумя заданными точками.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.spritesheet('diamonds', 'assets/sprites/diamonds32x24x5.png', { frameWidth: 32, frameHeight: 24 });
    }

    create ()
    {
        const group = this.add.group({ key: 'diamonds', frame: 3, frameQuantity: 50, setXY: { x: 32, y: 32, stepX: 14 }});

        //  Spread out the children between the 2 given values, using the string-based property
        Phaser.Actions.Spread(group.getChildren(), 'alpha', 0, 1);
    }
}

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

const game = new Phaser.Game(config);

Что делает Phaser.Actions.Spread?

Метод Phaser.Actions.Spread принимает массив игровых объектов (чаще всего — детей группы) и равномерно распределяет значение их конкретного свойства между минимальным и максимальным заданными значениями.

Проще говоря, если у вас есть 50 спрайтов, и вы хотите, чтобы их свойство alpha (прозрачность) плавно менялось от 0 (полностью прозрачный) у первого спрайта до 1 (полностью непрозрачный) у последнего, Spread сделает это одной строчкой кода. Он автоматически рассчитает шаг изменения для каждого следующего объекта в массиве.

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

Разбор примера кода: от загрузки до создания группы

В начале сцены в методе preload загружается спрайтшит — изображение, содержащее несколько кадров (спрайтов). Указывается базовый URL и путь к файлу, а также размер одного кадра.

this.load.spritesheet('diamonds', 'assets/sprites/diamonds32x24x5.png', { frameWidth: 32, frameHeight: 24 });

В методе create создается группа (Group) спрайтов. Группа — это удобный контейнер для управления множеством однотипных объектов. Параметры инициализации указывают, что нужно создать 50 спрайтов (frameQuantity: 50), используя кадр с индексом 3 из загруженного спрайтшита. Они будут расположены в ряд, начиная с точки (32, 32) с шагом в 14 пикселей по оси X.

const group = this.add.group({ key: 'diamonds', frame: 3, frameQuantity: 50, setXY: { x: 32, y: 32, stepX: 14 }});

Применение Spread для распределения прозрачности

После создания группы мы получаем массив её детей с помощью метода group.getChildren(). Именно этот массив передается первым аргументом в Phaser.Actions.Spread.

Второй аргумент — это строка с именем свойства, которое мы хотим изменить. В данном случае это 'alpha'.

Третий и четвертый аргументы — это минимальное и максимальное значения для этого свойства. Здесь alpha будет меняться от 0 до 1.

Phaser.Actions.Spread(group.getChildren(), 'alpha', 0, 1);

В результате выполнения этой строки первый спрайт в группе получит alpha = 0 (невидим), последний — alpha = 1, а все промежуточные спрайты — равномерно распределенные значения между 0 и 1. Так создается эффект плавного появления ряда спрайтов.

Где еще можно использовать Spread?

Spread работает с любыми числовыми свойствами игровых объектов Phaser. Это открывает большой простор для творчества.

* **Распределение по оси (`xилиy`)**: Можно создать не прямую линию, а дугу или диагональ, меняя координаты. * **Изменение масштаба (scaleX, scaleY)**: Создать ряд объектов, которые уменьшаются или увеличиваются от начала к концу. * **Градиент цвета (tint)**: Задать разную тонировку для объектов, если преобразовывать индекс в hex-цвет. * **Угол поворота (rotation)**: Повернуть каждый следующий спрайт на небольшой угол.

Важно помнить, что распределение происходит в соответствии с порядком объектов в переданном массиве. Порядок в группе обычно соответствует порядку добавления.

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

Phaser.Actions.Spread — это элегантный и производительный инструмент для парового задания свойств множеству объектов по закону линейного распределения. Он избавляет от написания циклов и ручных расчетов, делая код чище и понятнее. **Идеи для экспериментов:** 1. Примените Spread к свойству scale, чтобы создать «перспективу» — объекты, уменьшающиеся вдалеке. 2. Скомбинируйте распределение `xиy`, чтобы расставить объекты по синусоиде или окружности (рассчитав значения через Math.sin). 3. Используйте его не в create, а в update, динамически меняя диапазон значений в зависимости от времени или действий игрока, чтобы создать анимированный волновой эффект.