О чем этот пример
В игровом движке Phaser геометрические объекты, такие как прямоугольники, часто используются для обработки столкновений, организации сеток и управления зонами. Статический метод `Phaser.Geom.Rectangle.CopyFrom` позволяет эффективно копировать свойства одного прямоугольника в другой, избегая создания новых объектов и экономя ресурсы. Эта статья на практическом примере покажет, как использовать этот метод для создания интерактивной сетки, где прямоугольники динамически меняют размер, следуя за курсором.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
rectangles;
pointerRect;
graphics;
create ()
{
this.graphics = this.add.graphics({ lineStyle: { color: 0x0000aa }, fillStyle: { color: 0x0000aa, alpha: 0.5 } });
this.pointerRect = new Phaser.Geom.Rectangle(0, 0, 80, 60);
this.rectangles = [];
for (let x = 0; x < 10; x++)
{
this.rectangles[x] = [];
for (let y = 0; y < 10; y++)
{
this.rectangles[x][y] = new Phaser.Geom.Rectangle(x * 80, y * 60, 80, 60);
}
}
this.input.on('pointermove', pointer =>
{
const x = Math.floor(pointer.x / 80);
const y = Math.floor(pointer.y / 60);
this.pointerRect.setPosition(x * 80, y * 60);
Phaser.Geom.Rectangle.CopyFrom(this.pointerRect, this.rectangles[x][y]);
});
}
update ()
{
this.graphics.clear();
this.graphics.fillRectShape(this.pointerRect);
for (let x = 0; x < 10; x++)
{
for (let y = 0; y < 10; y++)
{
const rect = this.rectangles[x][y];
if (rect.width > 10)
{
rect.width *= 0.95;
rect.height *= 0.95;
}
this.graphics.strokeRectShape(rect);
}
}
}
}
const config = {
width: 800,
height: 600,
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Понимание геометрических объектов Phaser
В Phaser геометрические объекты, такие как Phaser.Geom.Rectangle, являются простыми контейнерами для данных (x, y, width, height). Они не отрисовываются автоматически и не имеют физики. Их основная роль — хранить координаты и размеры для вычислений.
В примере создаётся сетка из 10x10 прямоугольников. Каждый из них инициализируется с фиксированным размером 80x60 пикселей.
for (let x = 0; x < 10; x++)
{
this.rectangles[x] = [];
for (let y = 0; y < 10; y++)
{
this.rectangles[x][y] = new Phaser.Geom.Rectangle(x * 80, y * 60, 80, 60);
}
}
Также создаётся отдельный прямоугольник pointerRect, который будет представлять текущую позицию курсора в сетке.
Работа метода CopyFrom и обработка ввода
Метод Phaser.Geom.Rectangle.CopyFrom(sourceRect, destRect) копирует свойства `x,y,widthиheightиз исходного прямоугольника (sourceRect) в целевой (destRect`). Это мутирующая операция: она изменяет целевой объект, а не создаёт новый.
В примере обработчик события pointermove вычисляет, над какой ячейкой сетки находится курсор, позиционирует pointerRect в эту ячейку, а затем копирует его данные в соответствующий прямоугольник сетки.
this.input.on('pointermove', pointer =>
{
const x = Math.floor(pointer.x / 80);
const y = Math.floor(pointer.y / 60);
this.pointerRect.setPosition(x * 80, y * 60);
Phaser.Geom.Rectangle.CopyFrom(this.pointerRect, this.rectangles[x][y]);
});
Благодаря CopyFrom, прямоугольник в сетке мгновенно получает актуальные координаты курсорного прямоугольника. Это эффективнее, чем создавать новый экземпляр Rectangle каждый кадр.
Визуализация и анимация в методе update
Вся отрисовка происходит в методе update(). Сначала graphics.clear() очищает холст от предыдущего кадра. Затем заливается синим прямоугольник pointerRect.
this.graphics.clear();
this.graphics.fillRectShape(this.pointerRect);
Далее в двойном цикле происходит обход всех прямоугольников сетки. Если ширина прямоугольника больше 10 пикселей, она уменьшается на 5% каждый кадр, создавая эффект "сжатия".
if (rect.width > 10)
{
rect.width *= 0.95;
rect.height *= 0.95;
}
Затем каждый прямоугольник сетки обводится контуром с помощью strokeRectShape. Прямоугольник, в который только что скопировали данные (CopyFrom), на следующем кадре начнёт сжиматься снова, так как его размер был сброшен до 80x60.
Что попробовать дальше
Метод Phaser.Geom.Rectangle.CopyFrom — это простой и производительный инструмент для синхронизации состояния геометрических объектов. В рассмотренном примере он обеспечивает мгновенную реакцию сетки на движение курсора. Для экспериментов попробуйте: изменить логику сжатия (например, чтобы прямоугольники росли при наведении), использовать другие геометрические объекты (Circle, Triangle) с их методами копирования или применить CopyFrom для реализации простой системы выделения объектов (selection box) в стратегической игре.
