Phaser предоставляет гибкие инструменты для организации объектов в пространстве игры с использованием сетки. Сетка облегчает позиционирование, выравнивание и взаимодействие объектов, особенно в 2D-играх с тайловой графикой или структурированными уровнями. Основные концепции включают Grid и Snap, которые позволяют автоматизировать размещение объектов по фиксированным координатам.
Сетка (Grid) в Phaser — это логическая структура,
определяющая деление игрового пространства на равные ячейки. Она не
обязательно визуальна, но служит базой для позиционирования
объектов.
Инициализация сетки:
const gridSize = 32; // размер одной ячейки в пикселях
const cols = Math.floor(game.config.width / gridSize);
const rows = Math.floor(game.config.height / gridSize);
Здесь gridSize задаёт ширину и высоту ячейки.
cols и rows определяют количество ячеек по
горизонтали и вертикали, исходя из размеров канвы игры.
Вычисление позиции объекта по сетке:
function getGridPosition(col, row) {
return {
x: col * gridSize + gridSize / 2,
y: row * gridSize + gridSize / 2
};
}
const position = getGridPosition(5, 3);
player.setPosition(position.x, position.y);
Ключевой момент: координаты рассчитываются от центра ячейки для удобного выравнивания спрайтов.
Отображение сетки (опционально):
const graphics = this.add.graphics();
graphics.lineStyle(1, 0xffffff, 0.3);
for (let i = 0; i <= cols; i++) {
graphics.moveTo(i * gridSize, 0);
graphics.lineTo(i * gridSize, game.config.height);
}
for (let j = 0; j <= rows; j++) {
graphics.moveTo(0, j * gridSize);
graphics.lineTo(game.config.width, j * gridSize);
}
graphics.strokePath();
Отображение сетки полезно для отладки и визуальной привязки объектов, но в релизной версии можно скрывать графику.
Snap позволяет автоматически выравнивать объекты по ближайшей ячейке. Это особенно важно при динамическом размещении объектов, перемещении с помощью мыши или программного контроля.
Пример использования Snap для спрайта:
this.input.on('pointerdown', (pointer) => {
const snappedX = Math.round(pointer.x / gridSize) * gridSize;
const snappedY = Math.round(pointer.y / gridSize) * gridSize;
sprite.setPosition(snappedX + gridSize / 2, snappedY + gridSize / 2);
});
Ключевой момент: Math.round гарантирует, что
объект займёт ближайшую ячейку. При необходимости можно использовать
Math.floor или Math.ceil для смещения
привязки.
Snap при перемещении объектов:
Phaser поддерживает гибкую привязку через интерактивность спрайтов:
sprite.setInteractive();
this.input.setDraggable(sprite);
this.input.on('drag', (pointer, obj, dragX, dragY) => {
const snappedX = Math.round(dragX / gridSize) * gridSize;
const snappedY = Math.round(dragY / gridSize) * gridSize;
obj.setPosition(snappedX + gridSize / 2, snappedY + gridSize / 2);
});
Это позволяет создавать drag-and-drop с точной привязкой к сетке.
Grid и Snap вместе идеально подходят для создания тайловых уровней. Каждое изменение координат объекта может быть автоматически округлено до ячейки, что упрощает обработку столкновений и логики игры.
Создание карты с привязкой:
const map = [];
for (let row = 0; row < rows; row++) {
map[row] = [];
for (let col = 0; col < cols; col++) {
map[row][col] = null; // пустая ячейка
}
}
Размещение объектов на карте:
function placeTile(tile, col, row) {
const pos = getGridPosition(col, row);
tile.setPosition(pos.x, pos.y);
map[row][col] = tile;
}
Такой подход облегчает работу с игровым уровнем, позволяет проверять занятость ячеек и строить алгоритмы для ИИ или построения уровней.
Grid и Snap в Phaser образуют фундамент для точного позиционирования объектов, упрощая создание уровней, систем столкновений и динамических интерактивных элементов. Они позволяют перейти от хаотичного размещения к структурированному и предсказуемому миру игры.