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

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

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

Живой запуск

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

Исходный код


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

        const circles = [];

        for (let x = 0; x < 8; x++)
        {
            circles[x] = [];
            for (let y = 0; y < 6; y++)
            {
                circles[x][y] = new Phaser.Geom.Circle(50 + x * 100, 50 + y * 100, 50);
            }
        }

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

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

            redraw();
        });

        redraw();

        function redraw ()
        {
            graphics.clear();

            for (let x = 0; x < 8; x++)
            {
                for (let y = 0; y < 6; y++)
                {
                    graphics.fillCircleShape(circles[x][y]);
                }
            }
        }
    }
}

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

const game = new Phaser.Game(config);

Суть метода setEmpty

Метод setEmpty() — это часть API геометрических объектов в Phaser. Он мгновенно устанавливает радиус геометрической фигуры в ноль. Для круга это означает, что он становится точкой без площади и перестает отображаться при стандартной визуализации.

Ключевое отличие от простого удаления объекта из массива или сцены заключается в том, что сам объект (Phaser.Geom.Circle) продолжает существовать в памяти. Это позволяет: * Легко восстанавливать объект позже, устанавливая ему новый радиус. * Сохранять структуры данных (например, наш двумерный массив circles) без их перестроения. * Проверять состояние объекта через свойство empty, которое становится true после вызова setEmpty().

// Вызов метода для объекта circle
circle.setEmpty();

// Теперь circle.empty === true, а circle.radius === 0

Разбор примера: Сетка интерактивных кругов

Рассмотрим исходный код. В нем создается сетка 8x6 зеленых кругов. Каждый круг — это отдельный объект Phaser.Geom.Circle, сохраненный в двумерном массиве для удобства доступа по координатам.

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

        for (let x = 0; x < 8; x++) {
            circles[x] = [];
            for (let y = 0; y < 6; y++) {
                circles[x][y] = new Phaser.Geom.Circle(50 + x * 100, 50 + y * 100, 50);
            }
        }
        // ...
    }
}

Графический контекст graphics отвечает за отрисовку всех фигур. Функция redraw() очищает холст и заново рисует все круги из массива, включая те, чей радиус уже стал равен нулю.

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

Вся магия происходит в обработчике события pointerdown. Когда пользователь кликает по холсту, мы вычисляем индексы столбца (`x) и строки (y`) в нашей виртуальной сетке, основываясь на координатах клика.

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

    circles[x][y].setEmpty(); // Делаем выбранный круг "пустым"
    redraw(); // Обновляем изображение на холсте
});

После вызова circles[x][y].setEmpty() радиус целевого круга устанавливается в 0. Последующий вызов redraw() приводит к перерисовке сцены, и этот круг больше не отображается, создавая эффект его исчезновения. Важно, что объект в массиве circles[x][y] остается на своем месте, но становится "невидимым" для игрока.

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

Метод setEmpty() — это мощный и простой инструмент для управления состоянием геометрических объектов в Phaser. Вместо сложной логики добавления и удаления объектов из мира игры вы можете мгновенно переключать их видимость и функциональность. **Идеи для экспериментов:** 1. Создайте простой кликер, где setEmpty() имитирует разрушение объектов. 2. Реализуйте лабиринт, где проходы открываются при нажатии на скрытые переключатели (круги), которые затем "обнуляются". 3. Добавьте кнопку "Рестарт", которая пробегается по массиву circles и восстанавливает радиус каждого круга до исходного значения. 4. Используйте свойство empty для проверки условий в игровой логике (например, "все мишени поражены").