О чем этот пример
Добавление источников света и теней — один из самых эффектных способов повысить визуальную глубину и атмосферу вашей 2D-игры. В этой статье на примере кода из репозитория Phaser мы разберём, как быстро интегрировать систему динамического освещения, сделать его интерактивным и управлять им в реальном времени. Вы научитесь работать с пайплайном Light2D, создавать прожекторы, реагирующие на движение мыши, и управлять общим освещением сцены.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
var config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
width: 800,
height: 600,
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config);
var tilesprite;
function preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('brick', ['assets/normal-maps/brick.jpg', 'assets/normal-maps/brick_n.png']);
}
function create ()
{
tilesprite = this.add.tileSprite(400, 300, 800, 600, 'brick').setPipeline('Light2D');
this.lights.enable();
this.lights.setAmbientColor(0x808080);
var spotlight = this.lights.addLight(400, 300, 280).setIntensity(3);
this.input.on('pointermove', function (pointer) {
spotlight.x = pointer.x;
spotlight.y = pointer.y;
});
var i = 0;
this.input.on('pointerdown', (pointer) => {
if (i === 1) {
//this.lights.enable();
this.lights.active = true;
i = 0;
} else {
//this.lights.disable();
this.lights.active = false;
i = 1;
}
});
}
function update ()
{
tilesprite.tilePositionX += 0.3;
tilesprite.tilePositionY += 0.6;
}
Настройка сцены и загрузка текстур с картами нормалей
Пример начинается с базовой конфигурации игры. Ключевой момент — использование Phaser.WEBGL, так как система освещения работает только с этим рендерером.
var config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
width: 800,
height: 600,
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config);
В методе preload загружается не обычное изображение, а набор из цветовой текстуры и карты нормалей. Карта нормалей (файл с суффиксом _n) необходима для корректного расчёта того, как свет падает на поверхность, создавая иллюзию объёма.
function preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('brick', ['assets/normal-maps/brick.jpg', 'assets/normal-maps/brick_n.png']);
}
Создание фона и включение системы освещения
В фазе create мы создаём фон с помощью TileSprite. Важный шаг — установка пайплайна рендеринга Light2D для этого спрайта через метод .setPipeline('Light2D'). Без этого свет не будет влиять на объект.
tilesprite = this.add.tileSprite(400, 300, 800, 600, 'brick').setPipeline('Light2D');
Далее система освещения активируется методом this.lights.enable(). Метод this.lights.setAmbientColor(0x808080) устанавливает цвет окружающего (фонового) света. Серый цвет (0x808080) означает, что без активных источников объекты будут отображаться в половинной яркости.
this.lights.enable();
this.lights.setAmbientColor(0x808080);
Добавление интерактивного источника света
Теперь создадим основной источник света — прожектор. Метод this.lights.addLight(x, y, radius) создаёт точечный свет с заданным радиусом. Метод .setIntensity(3) увеличивает его яркость в три раза относительно стандартной.
var spotlight = this.lights.addLight(400, 300, 280).setIntensity(3);
Чтобы свет следовал за курсором мыши, мы подписываемся на событие pointermove. При каждом движении мыши координаты прожектора обновляются.
this.input.on('pointermove', function (pointer) {
spotlight.x = pointer.x;
spotlight.y = pointer.y;
});
Управление видимостью света по клику
Пример добавляет возможность включать и выключать все динамические источники света по клику мыши, оставляя только ambient-освещение. Для этого используется флаг this.lights.active. Обратите внимание, что это не то же самое, что this.lights.disable(), который отключает всю систему.
var i = 0;
this.input.on('pointerdown', (pointer) => {
if (i === 1) {
this.lights.active = true; // Включаем динамические источники света
i = 0;
} else {
this.lights.active = false; // Выключаем динамические источники света
i = 1;
}
});
Анимация фона для усиления эффекта
Чтобы продемонстрировать, как освещение работает с движущимися объектами, в функции update анимируется текстура фона. Изменение свойств tilePosition заставляет текстуру кирпича медленно смещаться, создавая иллюзию движения поверхности под динамическим светом.
function update ()
{
tilesprite.tilePositionX += 0.3;
tilesprite.tilePositionY += 0.6;
}
Это наглядно показывает, что освещение пересчитывается каждый кадр и корректно взаимодействует с анимированной геометрией.
Что попробовать дальше
Система освещения Phaser 3 — мощный и при этом достаточно простой инструмент. Вы можете создавать несколько источников света разного цвета и радиуса, привязывать их к игровым персонажам или событиям, а также комбинировать с другими эффектами. Для экспериментов попробуйте: изменить ambient-цвет на тёмно-синий для ночной сцены; добавить несколько статичных или мерцающих огней; привязать свет не к курсору, а к спрайту, следующему по сложной траектории.
