О чем этот пример
При создании множества игровых объектов часто требуется изменять их свойства не случайным образом, а по заданному алгоритму. Например, сделать так, чтобы спрайты в группе постепенно становились прозрачными от первого к последнему. Вручную перебирать все элементы и рассчитывать для каждого значение — долго и неудобно. В 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, динамически меняя диапазон значений в зависимости от времени или действий игрока, чтобы создать анимированный волновой эффект.
