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

Визуализация и взаимодействие — ключевые элементы геймдизайна. Часто нужно динамически управлять графическими объектами: скрывать, показывать или менять их стиль в зависимости от состояния. В этой статье разберём пример из официальной документации Phaser, который демонстрирует работу с геометрией эллипсов. Мы научимся использовать метод `isEmpty()` для проверки, является ли эллипс «пустым» (имеет нулевую или отрицательную ширину/высоту), и на основе этого менять его отображение с заливки на контур. Это полезно для создания анимаций, интерактивных подсказок или визуальных эффектов, где объект должен «исчезать» и «появляться».

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    ellipses;
    graphics;

    create ()
    {
        this.graphics = this.add.graphics({ lineStyle: { color: 0x00aaaa }, fillStyle: { color: 0x00aaaa }});

        this.ellipses = [];

        for (let y = 0; y < 5; y++)
        {
            for (let x = 0; x < 5; x++)
            {
                const relativeSize = Math.random() * 2 - 1;

                const ellipse = new Phaser.Geom.Ellipse(80 + x * 160, 60 + y * 120, relativeSize * 160, relativeSize * 120);

                this.ellipses.push(ellipse);
            }
        }
    }

    update ()
    {
        this.graphics.clear();

        for (let i = 0; i < this.ellipses.length; i++)
        {
            const ellipse = this.ellipses[i];

            ellipse.width += 0.8;
            ellipse.height += 0.6;

            if (ellipse.width >= 160 || ellipse.height >= 120)
            {
                ellipse.setSize(-160, -120);
            }

            if (!ellipse.isEmpty())
            {
                this.graphics.fillEllipseShape(ellipse);
            }
            else
            {
                this.graphics.strokeEllipseShape(ellipse);
            }
        }
    }
}

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

const game = new Phaser.Game(config);

Создание сцены и подготовка данных

В примере создаётся сцена, которая будет содержать массив эллипсов и объект Graphics для их отрисовки. В методе create() инициализируется холст для рисования и создаётся 25 эллипсов (5x5 сетка). Каждый эллипс имеет случайный относительный размер от -1 до 1, что позволяет сразу получить как положительные, так и «пустые» (с отрицательными размерами) фигуры.

class Example extends Phaser.Scene
{
    ellipses;
    graphics;

    create ()
    {
        this.graphics = this.add.graphics({ lineStyle: { color: 0x00aaaa }, fillStyle: { color: 0x00aaaa }});
        this.ellipses = [];
        for (let y = 0; y < 5; y++)
        {
            for (let x = 0; x < 5; x++)
            {
                const relativeSize = Math.random() * 2 - 1;
                const ellipse = new Phaser.Geom.Ellipse(80 + x * 160, 60 + y * 120, relativeSize * 160, relativeSize * 120);
                this.ellipses.push(ellipse);
            }
        }
    }
}

Динамическое изменение и проверка состояния

В методе update() происходит анимация: каждый кадр увеличиваются ширина и высота всех эллипсов. Когда размер достигает порогового значения (ширина >= 160 или высота >= 120), размер сбрасывается на отрицательные значения с помощью setSize(-160, -120). Это переводит эллипс в «пустое» состояние.

update ()
{
    this.graphics.clear();
    for (let i = 0; i < this.ellipses.length; i++)
    {
        const ellipse = this.ellipses[i];
        ellipse.width += 0.8;
        ellipse.height += 0.6;
        if (ellipse.width >= 160 || ellipse.height >= 120)
        {
            ellipse.setSize(-160, -120);
        }
    }
}

Использование метода isEmpty() для визуализации

Ключевой момент — проверка состояния эллипса с помощью метода isEmpty(). Этот метод возвращает true, если ширина или высота эллипса меньше или равна нулю. В зависимости от результата мы выбираем способ отрисовки: если эллипс не пустой, он заливается цветом (fillEllipseShape), если пустой — рисуется только его контур (strokeEllipseShape). Это создаёт эффект «мигания» или пульсации объектов.

if (!ellipse.isEmpty())
{
    this.graphics.fillEllipseShape(ellipse);
}
else
{
    this.graphics.strokeEllipseShape(ellipse);
}

Настройка и запуск игры

Пример завершается стандартной конфигурацией Phaser Game, где задаются размеры холста, тип рендерера и указывается класс сцены. Это базовая структура для любого проекта на Phaser.

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

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

Метод isEmpty() — простой, но мощный инструмент для контроля графики в Phaser. Он позволяет реагировать на изменения геометрии объектов в реальном времени. Попробуйте экспериментировать: измените пороговые значения для сброса размера, добавьте разные цвета для пустых и заполненных состояний или используйте эту логику для управления видимостью спрайтов в игре. Например, можно скрывать объекты при их «исчезновении» или запускать звуковые эффекты при изменении состояния.