О чем этот пример
Выравнивание игровых объектов — рутинная задача, но её можно оживить. Встроенный метод `Phaser.Actions.AlignTo` позволяет не просто статично расставлять спрайты, но и добавлять плавное, динамическое смещение. Это открывает двери для создания живых интерфейсов, эффектных меню или "дыхания" группы объектов без ручного расчёта позиций для каждого. В этой статье разберём пример, где группа синих блоков синхронно движется вправо-влево, будучи выровненной относительно ведущего красного драгоценного камня. Мы посмотрим, как работает выравнивание и как привязать к нему синусоиду для создания плавной анимации.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
this.y = 0;
this.gems = [];
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('red', 'assets/sprites/gem.png');
this.load.image('blue', 'assets/sprites/columns-blue.png');
}
create ()
{
// This is our 'lead' Sprite, the first one in the array
this.gems.push(this.add.sprite(200, 300, 'red'));
for (let i = 0; i < 8; i++)
{
// All of the blue gems will be aligned to the right of the red gem
this.gems.push(this.add.sprite(0, 0, 'blue'));
}
}
update ()
{
Phaser.Actions.AlignTo(this.gems, Phaser.Display.Align.RIGHT_CENTER, 0, Math.sin(this.y) * 8);
this.y += 0.1;
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и загрузка ассетов
В конструкторе класса сцены инициализируем два свойства: `yдля хранения текущего угла синусоиды и пустой массивgems` для хранения всех спрайтов, участвующих в выравнивании.
В методе preload загружаем два изображения. Обратите внимание на использование setBaseURL — это удобно, когда все ассеты лежат по одному базовому пути.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('red', 'assets/sprites/gem.png');
this.load.image('blue', 'assets/sprites/columns-blue.png');
}
Создание ведущего и ведомых спрайтов
В методе create формируем нашу группу. Ключевой момент — первый спрайт, добавляемый в массив, становится "лидером" или точкой отсчёта для операции AlignTo. Его позиция задаётся явно.
Остальные спрайты (синие колонны) создаются с координатами (0, 0), так как их конечная позиция будет полностью переопределена в update методом AlignTo.
create ()
{
// This is our 'lead' Sprite, the first one in the array
this.gems.push(this.add.sprite(200, 300, 'red'));
for (let i = 0; i < 8; i++)
{
// All of the blue gems will be aligned to the right of the red gem
this.gems.push(this.add.sprite(0, 0, 'blue'));
}
}
Магия динамического выравнивания в update
Вся анимация происходит в методе update, который вызывается на каждом кадре. Здесь используется статический метод Phaser.Actions.AlignTo.
Его первый аргумент — массив спрайтов. Второй — константа Phaser.Display.Align.RIGHT_CENTER. Она означает: "выровнять все спрайты по правому краю и центру по вертикали относительно предыдущего спрайта в массиве". Таким образом, первый синий спрайт выравнивается по правому краю красного, второй — по правому краю первого синего, и так далее.
Третий аргумент (смещение по X) равен 0. А вот четвёртый аргумент (смещение по Y) — это и есть источник динамики. Мы передаём результат вычисления Math.sin(this.y) * 8. Значение свойства this.y плавно увеличивается каждый кадр, заставляя синус колебаться между -1 и 1, что даёт итоговое смещение от -8 до 8 пикселей.
update ()
{
Phaser.Actions.AlignTo(this.gems, Phaser.Display.Align.RIGHT_CENTER, 0, Math.sin(this.y) * 8);
this.y += 0.1;
}
Конфигурация и запуск игры
Это стандартная конфигурация игры Phaser. Обратите внимание, что в свойстве scene передаётся не строка с ключом, а сам класс нашей сцены Example. Это допустимый и удобный способ.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Метод Phaser.Actions.AlignTo — это мощный инструмент для автоматического позиционирования групп объектов. Как мы увидели, его можно легко комбинировать с математическими функциями для создания живой, органической анимации без управления каждым объектом в отдельности.
Для экспериментов попробуйте:
1. Изменить константу выравнивания на LEFT_CENTER или BOTTOM_CENTER.
2. Задать отличное от нуля смещение по X, чтобы цепочка шла по диагонали.
3. Использовать Math.cos или комбинацию синусов для более сложных траекторий движения всей цепочки.
4. Применить этот подход к выравниванию текстовых элементов или кнопок в меню, добавив им лёгкого "дыхания".
