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

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

Версия 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('robot', [ 'assets/pics/equality-by-ragnarok.png', 'assets/normal-maps/equality-by-ragnarok_n.png' ]);
        this.load.image('atari', 'assets/sprites/atari400.png');
    }

    create ()
    {
        //  Enable lights and set a dark ambient color
        this.lights.enable().setAmbientColor(0x333333);

        //  Add an image and set it to use Lights2D
        const robot = this.add.image(-100, 0, 'robot').setOrigin(0).setScale(0.7);

        robot.setLighting(true);

        //  Our spotlight. 100px radius and white in color.
        const light = this.lights.addLight(180, 80, 200).setColor(0xffffff).setIntensity(2);

        //  Track the pointer
        this.input.on('pointermove', pointer =>
        {

            light.x = pointer.x;
            light.y = pointer.y;

        });
    }
}

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

const game = new Phaser.Game(config);

Включаем систему освещения

По умолчанию система освещения в Phaser 3 отключена, чтобы не нагружать рендеринг без необходимости. Ее активация — первый и обязательный шаг.

В методе create() сцены мы обращаемся к менеджеру освещения this.lights. Вызов метода .enable() включает систему. Сразу после этого полезно задать фоновый (ambient) цвет с помощью .setAmbientColor(). Этот цвет определяет, как будут выглядеть области сцены, не освещенные нашими источниками света. Темный цвет, например 0x333333, создает контраст и подчеркивает световые эффекты.

this.lights.enable().setAmbientColor(0x333333);

Подготавливаем объект для освещения

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

В примере мы создаем изображение робота и размещаем его частично за пределами видимой области (координата x = -100). Метод .setLighting(true) — это ключевой момент. Он сообщает рендереру, что при отрисовке этого объекта нужно учитывать данные системы освещения.

const robot = this.add.image(-100, 0, 'robot').setOrigin(0).setScale(0.7);
robot.setLighting(true);

Создаем и настраиваем источник света

Сердце нашего примера — прожектор. Мы создаем его через this.lights.addLight(), передавая начальные координаты (x, y) и радиус действия.

Созданный свет — это объект с набором методов для настройки. Мы сразу задаем ему белый цвет (.setColor(0xffffff)) и увеличиваем интенсивность в два раза по сравнению со стандартной (.setIntensity(2)). Интенсивность больше 1 делает свет ярче, меньше 1 — приглушеннее.

const light = this.lights.addLight(180, 80, 200).setColor(0xffffff).setIntensity(2);

Делаем свет интерактивным

Чтобы свет следовал за указателем мыши, мы подписываемся на событие pointermove. Каждый раз при движении курсора функция-обработчик получает объект pointer с его текущими координатами.

Внутри обработчика мы просто присваиваем эти координаты свойствам `xиyнашего объектаlight`. Phaser автоматически перерисовывает сцену, создавая плавную анимацию движения светового пятна.

this.input.on('pointermove', pointer => {
    light.x = pointer.x;
    light.y = pointer.y;
});

Важные детали конфигурации

Для работы системы освещения критически важен правильный рендерер. В конфигурации игры (config) необходимо указать type: Phaser.WEBGL. Система освещения Lights2D работает только в контексте WebGL и не будет функционировать при использовании рендерера Canvas (Phaser.CANVAS).

const config = {
    type: Phaser.WEBGL, // Обязательно WEBGL
    width: 800,
    height: 600,
    parent: 'phaser-example',
    scene: Example
};

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

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