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

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

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

Живой запуск

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

Исходный код


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

        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);
            }
        }

        const bigCircle = new Phaser.Geom.Circle(400, 300, 250);

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

            Phaser.Geom.Circle.CopyFrom(bigCircle, circles[x][y]);

            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);

Разбор примера: Сетка кругов и большой круг

В предоставленном примере создается сцена с двумя ключевыми элементами: сеткой из 48 маленьких кругов и одним большим кругом. Сетка служит визуальным полем, а большой круг — источником данных для копирования.

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);
    }
}
const bigCircle = new Phaser.Geom.Circle(400, 300, 250);

Код создает двумерный массив circles. Каждый элемент — это объект Phaser.Geom.Circle с уникальными координатами центра и радиусом 50 пикселей. Большой круг bigCircle располагается в центре сцены с радиусом 250 пикселей. Объекты Phaser.Geom.Circle здесь являются чисто математическими представлениями, без физических свойств.

Как работает метод CopyFrom

Сердце примера — статический метод Phaser.Geom.Circle.CopyFrom. Он не создает новый объект, а копирует свойства (координаты x, y и радиус) из исходного круга в целевой.

Phaser.Geom.Circle.CopyFrom(bigCircle, circles[x][y]);

В данном вызове bigCircle — источник данных (откуда копировать), а circles[x][y] — цель (в какой объект скопировать). После выполнения этой строки круг в ячейке [x][y] сетки мгновенно получает координаты центра (400, 300) и радиус 250, становясь идентичным bigCircle. Это мутация существующего объекта, что эффективнее, чем создание нового экземпляра через new.

Обработка ввода и визуализация

Интерактивность добавляется через обработчик события клика (pointerdown). При клике вычисляется индекс ячейки сетки, и для соответствующего круга вызывается CopyFrom.

this.input.on('pointerdown', pointer => {
    const x = Math.floor(pointer.x / 100);
    const y = Math.floor(pointer.y / 100);
    Phaser.Geom.Circle.CopyFrom(bigCircle, circles[x][y]);
    redraw();
});

Функция redraw отвечает за отрисовку. Она очищает холст graphics и заново рисует все круги сетки, включая измененный. Обратите внимание: graphics.fillCircleShape принимает объект геометрии для отрисовки.

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

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

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

Такой подход полезен для: * **Областей применения заклинаний:** Одна геометрия-шаблон для разных кастов. * **Зон спавна:** Быстрое копирование границ зоны для нескольких точек появления врагов. * **Оптимизации:** Снижение нагрузки на сборщик мусора за счет повторного использования объектов, а не создания новых.

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

Метод Phaser.Geom.Circle.CopyFrom предоставляет производительный и удобный способ клонирования геометрических данных. Он идеально подходит для сценариев, где множество объектов должны наследовать свойства от общего шаблона. Для экспериментов попробуйте: применить этот метод к другим геометрическим объектам Phaser, например, Rectangle; создать несколько «шаблонных» кругов с разными радиусами и переключаться между ними по клику; или интегрировать эту логику с физическим телом (Arcade Physics) для динамического изменения зон столкновений.