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

В игровом движке Phaser работа с геометрией — это основа для коллизий, зон взаимодействия и визуальных эффектов. Класс `Phaser.Geom.Ellipse` предоставляет мощные методы для управления эллипсами, один из которых — `setEmpty`. Эта статья покажет, как использовать `setEmpty` для динамического "удаления" эллипсов из отрисовки, что полезно для создания интерактивных игровых полей, скрытия областей или управления состоянием объектов. Вы научитесь применять этот метод на практике, управляя массивом фигур и перерисовывая сцену по клику.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const graphics = this.add.graphics({ fillStyle: { color: 0x00aaaa } });

        const ellipses = [];

        for (let x = 0; x < 10; x++)
        {
            ellipses[x] = [];
            for (let y = 0; y < 10; y++)
            {
                ellipses[x][y] = new Phaser.Geom.Ellipse(40 + x * 80, 30 + y * 60, 80, 60);
            }
        }

        this.input.on('pointerdown', pointer =>
        {
            const x = Math.floor(pointer.x / 80);
            const y = Math.floor(pointer.y / 60);

            ellipses[x][y].setEmpty();

            redraw();
        });

        redraw();

        function redraw ()
        {
            graphics.clear();

            for (let x = 0; x < 10; x++)
            {
                for (let y = 0; y < 10; y++)
                {
                    graphics.fillEllipseShape(ellipses[x][y]);
                }
            }
        }
    }
}

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

const game = new Phaser.Game(config);

Подготовка сетки эллипсов

В начале сцены создаётся графический объект graphics для отрисовки фигур и двумерный массив ellipses, который будет хранить 100 экземпляров Phaser.Geom.Ellipse. Каждый эллипс позиционируется с шагом 80 пикселей по горизонтали и 60 по вертикали, образуя сетку 10x10.

const graphics = this.add.graphics({ fillStyle: { color: 0x00aaaa } });
const ellipses = [];

for (let x = 0; x < 10; x++)
{
    ellipses[x] = [];
    for (let y = 0; y < 10; y++)
    {
        ellipses[x][y] = new Phaser.Geom.Ellipse(40 + x * 80, 30 + y * 60, 80, 60);
    }
}

Функция redraw очищает холст graphics и заново отрисовывает все эллипсы из массива с помощью graphics.fillEllipseShape. Изначально сетка выглядит как цельное поле из залитых фигур.

Обработка клика и применение setEmpty

Для интерактивности добавляется обработчик события pointerdown. При клике вычисляются индексы `xиyв массивеellipsesна основе координат курсора. Затем вызывается методsetEmpty` для выбранного эллипса.

this.input.on('pointerdown', pointer =>
{
    const x = Math.floor(pointer.x / 80);
    const y = Math.floor(pointer.y / 60);

    ellipses[x][y].setEmpty();

    redraw();
});

Метод setEmpty изменяет внутренние свойства эллипса (например, ширину и высоту) так, что он становится "пустым" — при отрисовке его форма не отображается. После изменения вызывается redraw, чтобы обновить графику. Важно: сам объект эллипса остаётся в массиве, но визуально исчезает.

Как работает setEmpty и перерисовка

Метод setEmpty класса Phaser.Geom.Ellipse сбрасывает геометрические параметры фигуры, делая её невидимой для методов отрисовки, таких как fillEllipseShape. Это отличается от удаления объекта из памяти — эллипс остаётся частью структуры данных, что позволяет позже восстановить его (например, через setTo).

function redraw ()
{
    graphics.clear();

    for (let x = 0; x < 10; x++)
    {
        for (let y = 0; y < 10; y++)
        {
            graphics.fillEllipseShape(ellipses[x][y]);
        }
    }
}

Функция redraw проходит по всему массиву и отрисовывает каждый эллипс, включая "пустые". Для пустых эллипсов fillEllipseShape не производит видимого вывода, создавая эффект исчезновения. Такой подход удобен для управления видимостью без пересоздания объектов.

Практическое применение в играх

Техника с setEmpty полезна в различных игровых механиках. Например, можно создать поле для игры в «крестики-нолики», где эллипсы представляют ячейки, исчезающие при занятии. Или реализовать разрушаемую карту, где клик "убирает" часть terrain.

// Пример: проверка, пуст ли эллипс, перед действием
if (!ellipses[x][y].isEmpty()) {
    ellipses[x][y].setEmpty();
    redraw();
}

Используйте метод isEmpty для проверки состояния эллипса. Это позволяет избежать повторных действий или реализовать логику переключения (исчезновение/появление). Подход экономит ресурсы, так как не требует удаления и создания объектов в runtime.

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

Метод setEmpty в Phaser.Geom.Ellipse — это простой способ управлять видимостью геометрических фигур, сохраняя их в памяти. Он идеален для интерактивных сеток, динамических уровней или визуальных эффектов. Для экспериментов попробуйте: добавить восстановление эллипсов через setTo, изменить цвет при клике или связать setEmpty с физическими телами для создания разрушаемых препятствий.