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

В игровом движке Phaser работа с геометрией часто выходит за рамки простого отображения статичных фигур. Этот пример демонстрирует, как с помощью метода `Phaser.Geom.Rectangle.Scale()` можно создавать динамические, интерактивные визуальные эффекты, например, постепенное «выращивание» прямоугольника от центра экрана. Такой подход полезен для визуализации зон поражения, ауры персонажей, волновых эффектов или просто для создания стилизованных переходов и заставок.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const rect = new Phaser.Geom.Rectangle(0, 0, 8, 6);

        const graphics = this.add.graphics({ lineStyle: { color: 0x0000aa } });

        redraw(1.2, 1.2);

        this.input.on('pointermove', pointer =>
        {
            redraw(1.05 + pointer.x / 800, 1.05 + pointer.y / 600);
        });

        function redraw (scaleX, scaleY)
        {
            graphics.clear();

            rect.setTo(0, 0, 8, 6);

            while (rect.width < 800 || rect.height < 600)
            {
                Phaser.Geom.Rectangle.CenterOn(rect, 400, 300);

                graphics.strokeRectShape(rect);

                Phaser.Geom.Rectangle.Scale(rect, scaleX, scaleY);
            }
        }
    }
}

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

const game = new Phaser.Game(config);

Инициализация базовых объектов

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

const rect = new Phaser.Geom.Rectangle(0, 0, 8, 6);
const graphics = this.add.graphics({ lineStyle: { color: 0x0000aa } });

Прямоугольник rect инициализируется с минимальными размерами (8x6 пикселей). Объект graphics настраивается на отрисовку только контура (lineStyle) синим цветом (0x0000aa). Изначальный вызов функции redraw с параметрами 1.2 запускает первую отрисовку.

Организация интерактивности

Для создания интерактивного эффекта мы подписываемся на событие перемещения указателя мыши (pointermove). Координаты курсора используются для расчета коэффициентов масштабирования.

this.input.on('pointermove', pointer =>
{
    redraw(1.05 + pointer.x / 800, 1.05 + pointer.y / 600);
});

Формула 1.05 + pointer.x / 800 гарантирует, что коэффициент масштабирования по оси X всегда будет больше единицы (минимум 1.05, максимум чуть больше 2.05). Аналогично для оси Y. Таким образом, движение курсора в правый нижний угол экрана увеличивает коэффициенты масштабирования, заставляя прямоугольник расти быстрее.

Логика отрисовки и масштабирования

Вся магия происходит внутри функции redraw. Её задача — очистить предыдущий кадр, сбросить прямоугольник к исходному размеру, а затем в цикле масштабировать его до заполнения экрана.

function redraw (scaleX, scaleY)
{
    graphics.clear();
    rect.setTo(0, 0, 8, 6);

    while (rect.width < 800 || rect.height < 600)
    {
        Phaser.Geom.Rectangle.CenterOn(rect, 400, 300);
        graphics.strokeRectShape(rect);
        Phaser.Geom.Rectangle.Scale(rect, scaleX, scaleY);
    }
}

Цикл while выполняется до тех пор, пока ширина ИЛИ высота прямоугольника не станет больше или равна размерам холста (800x600). На каждой итерации: 1. Phaser.Geom.Rectangle.CenterOn() перемещает прямоугольник в центр экрана (координаты 400, 300). Это критически важно для эффекта роста из центра. 2. graphics.strokeRectShape() отрисовывает текущее состояние прямоугольника. 3. Phaser.Geom.Rectangle.Scale() применяет переданные коэффициенты scaleX и scaleY к прямоугольнику, изменяя его ширину и высоту на месте (in-place).

Конфигурация и запуск игры

Финальная часть — стандартная конфигурация приложения Phaser. Здесь задается размер холста, указывается корневой класс сцены и создается экземпляр игры.

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

Ключевой параметр scene: Example указывает движку, какой класс использовать в качестве основной сцены. Размеры width и height соответствуют условиям в цикле отрисовки (rect.width < 800).

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

Этот пример наглядно показывает, как несколько простых методов геометрического API Phaser (Scale, CenterOn) в сочетании с интерактивностью могут порождать сложные визуальные паттерны. Для экспериментов попробуйте изменить начальный размер прямоугольника, цвет или стиль линии, добавить градиентную заливку внутри цикла или использовать нелинейные формулы для расчета коэффициентов масштабирования (например, синусоидальную зависимость от времени). Это может стать основой для эффектов магических щитов, радарных импульсов или абстрактных визуализаторов.