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

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

Версия 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('card0', 'assets/games/card-memory-game/cards/card-0.png');
        this.load.image('card1', 'assets/games/card-memory-game/cards/card-1.png');
        this.load.image('card2', 'assets/games/card-memory-game/cards/card-2.png');
        this.load.image('card3', 'assets/games/card-memory-game/cards/card-3.png');
        this.load.image('card4', 'assets/games/card-memory-game/cards/card-4.png');
        this.load.image('card5', 'assets/games/card-memory-game/cards/card-5.png');
    }

    create ()
    {
        const cards = [];

        for (let i = 0; i < 6; i++)
        {
            const card = this.add.image(this.sys.scale.width / 2, this.sys.scale.height / 2, 'card' + i);
            card.setScale(2);
            cards.push(card);
        }

        Phaser.Actions.GridAlign(cards, {
            width: 3,
            height: 2,
            cellWidth: 250,
            cellHeight: 270,
            x: 100,
            y: 100
        });

        // Default shine.
        Phaser.Actions.AddEffectShine(cards[0]);

        // Shine from a different angle. Appears in a different corner.
        Phaser.Actions.AddEffectShine(cards[1], { direction: -0.5 });

        // Shine with different radius.
        Phaser.Actions.AddEffectShine(cards[2], { radius: 0.1 });

        // Shine with custom color and animation.
        Phaser.Actions.AddEffectShine(cards[3], {
            radius: 0.2,
            colorFactor: [ 0, 1, 1.5, 1 ],
            direction: Math.PI / 2, // Down
            ease: 'Quad.inout',
            scale: 1, // Shorter travel distance
            yoyo: true
        });

        // Shine with custom gradient.
        // Note that the gradient is in triangular repeat mode, so the gradient is reflected.
        Phaser.Actions.AddEffectShine(cards[4], {
            bands: [
                {
                    colorStart: [ 1, 0, 0, 0 ],
                    colorEnd: [ 1, 1, 1, 1 ],
                    start: 0.2,
                    size: 0.1,
                    interpolation: 4
                },
                {
                    colorStart: [ 1, 1, 1, 1 ],
                    colorEnd: [ 0, 0, 1, 0 ],
                    size: 0.2,
                    interpolation: 4
                }
            ],
            ease: 'Cubic.inout',
            yoyo: true
        });

        // Shine with reveal.
        Phaser.Actions.AddEffectShine(cards[5], { reveal: true });
    }
}

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

const game = new Phaser.Game(config);

Подготовка сцены и расположение объектов

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

Ключевой момент — использование Phaser.Actions.GridAlign для автоматического выравнивания массива карт в сетку 3x2. Это избавляет от ручного расчета координат для каждого объекта.

Phaser.Actions.GridAlign(cards, {
    width: 3,
    height: 2,
    cellWidth: 250,
    cellHeight: 270,
    x: 100,
    y: 100
});

Базовое сияние

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

// Default shine.
Phaser.Actions.AddEffectShine(cards[0]);

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

Настройка направления и размера

Параметр direction определяет угол (в радианах), откуда начинается свечение. Значение `0соответствует направлению вправо, аMath.PI/2` — вниз. Отрицательные значения меняют угол.

Параметр radius задает размер светлой полосы относительно ширины объекта. Меньшее значение создает тонкую линию, большее — широкую область свечения.

// Shine from a different angle. Appears in a different corner.
Phaser.Actions.AddEffectShine(cards[1], { direction: -0.5 });

// Shine with different radius.
Phaser.Actions.AddEffectShine(cards[2], { radius: 0.1 });

Продвинутая анимация и цвет

Вы можете полностью кастомизировать анимацию. Параметр colorFactor — это массив из четырех чисел [R, G, B, A], умножаемых на исходный цвет текстуры. Параметр scale управляет длиной пути свечения (1 = по ширине объекта). yoyo: true заставляет анимацию проигрываться вперед и назад, создавая пульсирующий эффект.

Phaser.Actions.AddEffectShine(cards[3], {
    radius: 0.2,
    colorFactor: [ 0, 1, 1.5, 1 ], // Усиливает зеленый и синий каналы
    direction: Math.PI / 2, // Движение сверху вниз
    ease: 'Quad.inout',
    scale: 1,
    yoyo: true
});

Создание сложных градиентов с `bands`

Для максимального контроля над внешним видом свечения используйте параметр bands. Он принимает массив объектов, каждый из которых описывает одну полосу градиента. Вы можете задавать начальный (colorStart) и конечный (colorEnd) цвет в формате RGBA, позицию (start), ширину полосы (size) и тип интерполяции цвета (interpolation).

Phaser.Actions.AddEffectShine(cards[4], {
    bands: [
        {
            colorStart: [ 1, 0, 0, 0 ], // Прозрачный красный
            colorEnd: [ 1, 1, 1, 1 ],   // Белый
            start: 0.2,
            size: 0.1,
            interpolation: 4
        },
        {
            colorStart: [ 1, 1, 1, 1 ], // Белый
            colorEnd: [ 0, 0, 1, 0 ],   // Прозрачный синий
            size: 0.2,
            interpolation: 4
        }
    ],
    ease: 'Cubic.inout',
    yoyo: true
});

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

Эффект "раскрытия" с параметром `reveal`

Особый режим работы эффекта активируется флагом reveal: true. В этом случае сияние не просто накладывается поверх текстуры, а временно "раскрывает" ее, создавая впечатление, что объект проявляется из-под светового луча. Это отличный выбор для анимации появления скрытых объектов или элементов интерфейса.

// Shine with reveal.
Phaser.Actions.AddEffectShine(cards[5], { reveal: true });

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

Метод Phaser.Actions.AddEffectShine — это мощный и гибкий инструмент для добавления полировки вашей игре. Он работает не только с изображениями, но и с текстом, графикой и другими объектами. Для экспериментов попробуйте привязать запуск эффекта к событиям ввода (клику, наведению), комбинировать несколько эффектов на одном объекте с разной задержкой или динамически менять параметры colorFactor в зависимости от состояния игрового объекта (например, подсвечивать поврежденный юнит красным свечением).