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

Маскирование — мощный приём для создания визуальных эффектов, но работа с масками вручную может быть сложной. Phaser 3 предоставляет удобный метод `Phaser.Actions.AddMaskShape`, который автоматически создаёт маску для отображения объекта с мягкими, размытыми границами. Это особенно полезно для создания плавных переходов, выделения ключевых игровых элементов или добавления атмосферных эффектов без подготовки отдельных текстур в графическом редакторе. В этой статье мы разберём, как это работает на практическом примере с анимированным спрайтом.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    cougar;

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('cougar', 'assets/pics/cougar-ihsf.png');
    }

    create ()
    {
        const cougar = this.add.image(400, 300, 'cougar');
        this.cougar = cougar;

        Phaser.Actions.AddMaskShape(cougar, {
            useInternal: true,
            blurRadius: 8,
            padding: 64
        });
    }

    update (time)
    {
        this.cougar.setPosition(
            400 + 16 * Math.cos(time / 100),
            300 + 8 * Math.sin(time / 78.7)
        )
        .setScale(1 + 0.02 * Math.sin(time / 45.9))
        .setRotation(0.1 * Math.cos(time / 89));
    }
}

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

const game = new Phaser.Game(config);

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

Метод Phaser.Actions.AddMaskShape — это высокоуровневая функция-хелпер. Её основная задача — автоматически создать геометрическую фигуру (по умолчанию прямоугольник) и наложить её на указанный игровой объект в качестве маски с мягкими краями.

Эта операция выполняется в три шага: 1. Создаётся новая графическая фигура (Phaser.GameObjects.Graphics), которая и будет служить маской. 2. К этой фигуре применяется размытие (blurRadius), которое и создаёт эффект мягкого, полупрозрачного края. 3. Фигура назначается маской для переданного объекта (например, изображения).

Ключевое преимущество — вся эта цепочка действий инкапсулирована в один вызов, что экономит время и упрощает код.

Анализ кода: Загрузка и создание маски

В примере мы видим классическую структуру сцены Phaser. В методе preload загружается изображение. В create происходит самое интересное: создаётся спрайт и тут же к нему применяется маска.

create ()
{
    const cougar = this.add.image(400, 300, 'cougar');
    this.cougar = cougar;

    Phaser.Actions.AddMaskShape(cougar, {
        useInternal: true,
        blurRadius: 8,
        padding: 64
    });
}

Разберём параметры вызова AddMaskShape: * **Первый аргумент (cougar)**: Игровой объект (в данном случае Image), к которому будет применена маска. * useInternal: true: Важный флаг. Он указывает, что для маскирования должна использоваться внутренняя, невидимая текстура объекта. Это необходимо для корректной работы эффекта размытия краёв. * blurRadius: 8: Сила размытия границы маски в пикселях. Чем больше значение, тем шире и плавнее будет переход от непрозрачной области к прозрачной. * padding: 64: Отступ, который добавляется вокруг исходного объекта при создании маски. Это гарантирует, что мягкий край маски не будет обрезан и будет виден полностью, даже если объект движется или вращается.

Анимация: Движение, масштаб и вращение

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

update (time)
{
    this.cougar.setPosition(
        400 + 16 * Math.cos(time / 100),
        300 + 8 * Math.sin(time / 78.7)
    )
    .setScale(1 + 0.02 * Math.sin(time / 45.9))
    .setRotation(0.1 * Math.cos(time / 89));
}

Здесь используется текущее игровое время (time) для плавного изменения свойств: * setPosition: Задаёт эллиптическое движение спрайта вокруг точки (400, 300) с помощью тригонометрических функций Math.cos и Math.sin. Разные делители для time по осям X и Y создают неравномерную, интересную траекторию. * setScale: Плавно пульсирует размер спрайта, создавая эффект лёгкого дыхания. * setRotation: Медленно вращает спрайт вокруг своей центральной точки.

Маска, созданная AddMaskShape, идеально адаптируется ко всем этим изменениям в реальном времени.

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

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

* **Выделение объекта**: Сделать маску для спрайта игрока или важного предмета, чтобы он визуально выделялся на фоне. * **Плавное появление/исчезание**: Анимируя параметры маски (например, её размер), можно создать эффект мягкого растворения объекта. * **Создание "световых пятен"**: Используйте маску поверх тёмного слоя для имитации света от фонаря или магического свечения.

AddMaskShape может принимать и другие параметры конфигурации для кастомизации формы маски (например, shape для определения пользовательской геометрии). Изучите официальную документацию Phaser для полного списка опций.

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

Phaser.Actions.AddMaskShape — это элегантный и производительный инструмент для добавления сложных визуальных эффектов малыми усилиями. Он избавляет разработчика от рутинной работы по созданию и управлению масками вручную. Для экспериментов попробуйте менять значения blurRadius и padding в реальном времени, привязывая их к игровым событиям (например, к здоровью персонажа), или примените маску не к изображению, а к целой группе (Phaser.GameObjects.Group) объектов.