О чем этот пример
При создании интерфейсов, тайловых полей или декоративных элементов часто требуется расположить множество игровых объектов в виде ровной сетки. Ручной расчет координат для каждого спрайта — утомительная и подверженная ошибкам задача. Phaser предоставляет мощный и простой инструмент для автоматического выравнивания — метод `Phaser.Actions.GridAlign`. Эта статья покажет, как с его помощью мгновенно создавать идеально ровные сетки из десятков объектов, экономя время и упрощая код.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bg', 'assets/skies/deepblue.png');
this.load.spritesheet('diamonds', 'assets/sprites/diamonds32x24x5.png', { frameWidth: 32, frameHeight: 24 });
}
create ()
{
this.add.image(400, 300, 'bg');
const group = this.add.group({
key: 'diamonds',
frame: [ 0, 1, 2, 3, 4 ],
frameQuantity: 40
});
Phaser.Actions.GridAlign(group.getChildren(), {
width: 20,
height: 10,
cellWidth: 32,
cellHeight: 32,
x: 80,
y: 140
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка группы спрайтов
Перед выравниванием необходимо создать группу объектов. В Phaser группа (Group) — это удобный контейнер для управления множеством однотипных игровых объектов (спрайтов, изображений). В методе create мы загружаем фон и создаем группу из спрайтов алмазов.
const group = this.add.group({
key: 'diamonds',
frame: [ 0, 1, 2, 3, 4 ],
frameQuantity: 40
});
Здесь мы создаем группу с ключом 'diamonds' (загруженный спрайтшит). Параметр frame — это массив индексов кадров (фреймов) из спрайтшита, которые будут использованы. Параметр frameQuantity указывает общее количество создаваемых спрайтов (40). Phaser равномерно распределит указанные фреймы среди всех созданных объектов. В итоге в группе окажется 40 спрайтов-алмазов пяти разных цветов.
Магия Phaser.Actions.GridAlign
Когда группа создана, но все спрайты находятся в одной точке (0, 0 по умолчанию), наступает время для Phaser.Actions.GridAlign. Этот статический метод принимает массив объектов и конфигурационный объект, а затем пересчитывает координаты (`x,y`) каждого переданного объекта, располагая их по сетке.
Phaser.Actions.GridAlign(group.getChildren(), {
width: 20,
height: 10,
cellWidth: 32,
cellHeight: 32,
x: 80,
y: 140
});
Первый аргумент — group.getChildren() — это массив всех спрайтов, содержащихся в группе. Второй аргумент — объект с настройками сетки.
Разбираем параметры выравнивания
Конфигурационный объект GridAlign дает полный контроль над расположением сетки. Давайте разберем каждое свойство:
{
width: 20, // Количество столбцов в сетке
height: 10, // Количество строк в сетке
cellWidth: 32, // Ширина одной ячейки в пикселях
cellHeight: 32,// Высота одной ячейки в пикселях
x: 80, // Начальная координата X для всей сетки
y: 140 // Начальная координата Y для всей сетки
}
* width и height: Определяют размерность сетки (20x10). Метод берет первые width * height объектов из переданного массива (в нашем случае 20*10=200, но у нас только 40 спрайтов). Объекты заполняют сетку построчно, слева направо.
* cellWidth и cellHeight: Задают размер ячейки. Координаты каждого следующего спрайта в строке увеличиваются на cellWidth, а при переходе на новую строку — на cellHeight.
* `xиy`: Это координаты верхнего левого угла всей сетки на игровом поле. Все расчеты позиций начинаются от этой точки.
Как работает алгоритм выравнивания
Метод проходит по массиву объектов в цикле, вычисляя позицию для каждого на основе его индекса в массиве. Псевдологика расчета позиции для объекта с индексом `i` выглядит так:
// Вычисление столбца и строки для текущего объекта
let column = i % width; // Остаток от деления — позиция в строке
let row = Math.floor(i / width); // Целая часть от деления — номер строки
// Расчет финальных координат
object.x = startX + (column * cellWidth);
object.y = startY + (row * cellHeight);
Таким образом, первый объект (i=0) попадет в ячейку (0,0), второй (i=1) — в (1,0), двадцатый (i=19) — в (19,0), а двадцать первый (i=20) — уже на новую строку, в ячейку (0,1). Phaser делает это автоматически для всех переданных объектов.
Что попробовать дальше
Phaser.Actions.GridAlign — это невероятно полезный инструмент для быстрого и аккуратного расположения объектов. Он избавляет от необходимости писать вложенные циклы и ручные расчеты координат. Для экспериментов попробуйте изменить параметры cellWidth и cellHeight, чтобы создать разреженную или плотную сетку. Или используйте Phaser.Actions.RandomRectangle для хаотичного, но вписанного в заданную область, размещения объектов из той же группы. Комбинируя разные методы из класса Phaser.Actions, вы можете создавать сложные паттерны и анимации начального расположения игровых элементов.
