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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    direction = 1;
    rect;
    graphics;

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

        this.rect = new Phaser.Geom.Rectangle(400, 300, 0, 0);
    }

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

        this.rect.width += 2.4 * this.direction;
        this.rect.height += 1.8 * this.direction;

        if (this.rect.width * this.direction >= 200)
        {
            this.direction *= -1;
        }

        if (!this.rect.isEmpty())
        {
            this.graphics.fillRectShape(this.rect);
        }
        else
        {
            this.graphics.strokeRectShape(this.rect);
        }
    }
}

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

const game = new Phaser.Game(config);

Разбор сцены и инициализации

В примере создается базовая сцена Phaser, которая динамически меняет размеры прямоугольника и визуализирует его состояние. Ключевые поля класса:

- direction: управляет ростом или сжатием прямоугольника (1 для увеличения, -1 для уменьшения). - rect: экземпляр Phaser.Geom.Rectangle, начальные размеры которого равны нулю. - graphics: объект Graphics для отрисовки прямоугольника на холсте.

В методе create() инициализируются графика и прямоугольник с нулевой шириной и высотой, расположенный в центре экрана (координаты 400, 300).

create ()
{
    this.graphics = this.add.graphics({ lineStyle: { color: 0x0000ff }, fillStyle: { color: 0x0000ff }});
    this.rect = new Phaser.Geom.Rectangle(400, 300, 0, 0);
}

Логика обновления и изменения размера

В методе update() происходит анимация прямоугольника. Каждый кадр графика очищается, а размеры прямоугольника изменяются на фиксированные значения, умноженные на direction. Это создает эффект «пульсации»: прямоугольник растет, а затем сжимается.

update ()
{
    this.graphics.clear();
    this.rect.width += 2.4 * this.direction;
    this.rect.height += 1.8 * this.direction;
    if (this.rect.width * this.direction >= 200)
    {
        this.direction *= -1;
    }

Условие this.rect.width * this.direction >= 200 инвертирует направление, когда ширина достигает 200 пикселей при росте или падает до отрицательных значений при сжатии. Умножение на direction нужно, чтобы условие работало в обоих направлениях.

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

Самая важная часть — проверка this.rect.isEmpty(). Метод isEmpty() возвращает true, если ширина или высота прямоугольника меньше или равны нулю. В зависимости от результата выбирается способ отрисовки:

- Если прямоугольник не пуст (isEmpty() вернул false), он заливается цветом с помощью fillRectShape(). - Если пуст (true), отрисовывается только его контур через strokeRectShape().

if (!this.rect.isEmpty())
{
    this.graphics.fillRectShape(this.rect);
}
else
{
    this.graphics.strokeRectShape(this.rect);
}

Таким образом, когда прямоугольник сжимается до нулевых размеров, на экране виден только контур (точка в центре), а при появлении площади — залитая синяя фигура.

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

Пример завершается стандартной конфигурацией Phaser Game. Важно отметить, что сцена Example передается в конфиг, что обеспечивает корректную работу анимации.

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

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

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