О чем этот пример
Создание анимированных сцен часто требует одновременного воздействия на множество объектов. Вручную управлять вращением каждого спрайта — утомительно и неэффективно. В статье рассмотрим, как использовать встроенный модуль `Phaser.Actions` для плавного и синхронного вращения целой группы объектов всего одной строкой кода. Этот подход идеально подходит для создания фоновых анимаций, визуальных эффектов и интерактивных элементов, где важна производительность и чистота кода.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
this.gingerbreads = [];
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('gingerbread', 'assets/sprites/gingerbread.png');
}
create ()
{
for (let i = 0; i < 26; i++)
{
this.gingerbreads.push(this.add.image(i * 32, 300, 'gingerbread'));
}
}
update ()
{
Phaser.Actions.Angle(this.gingerbreads, 1.5, 0.1);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и загрузка ресурсов
Класс сцены наследуется от Phaser.Scene. В конструкторе инициализируется пустой массив gingerbreads, который будет хранить ссылки на все создаваемые спрайты.
class Example extends Phaser.Scene
{
constructor ()
{
super();
this.gingerbreads = [];
}
В методе preload задается базовый URL для загрузки и загружается одно изображение спрайта. Удобно использовать setBaseURL, чтобы не указывать полный путь для каждого ресурса.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('gingerbread', 'assets/sprites/gingerbread.png');
}
Создание ряда спрайтов
В методе create в цикле создается 26 спрайтов. Каждый новый спрайт добавляется на сцену с помощью this.add.image и помещается в массив gingerbreads. Координата X каждого следующего спрайта увеличивается на 32 пикселя, формируя горизонтальный ряд.
create ()
{
for (let i = 0; i < 26; i++)
{
this.gingerbreads.push(this.add.image(i * 32, 300, 'gingerbread'));
}
}
Массовое вращение через Phaser.Actions
Сердце примера — метод update, который вызывается на каждом кадре игры. Здесь используется статический метод Phaser.Actions.Angle. Он применяет изменение угла ко всем объектам в переданном массиве.
update ()
{
Phaser.Actions.Angle(this.gingerbreads, 1.5, 0.1);
}
Разберем аргументы функции:
1. this.gingerbreads — массив объектов (в нашем случае спрайтов), к которым нужно применить действие.
2. 1.5 — величина (step), на которую будет изменяться угол каждого объекта за вызов. Положительное значение означает вращение по часовой стрелке.
3. 0.1 — шаг (rate) для вычисления конечного значения. Фактически, итоговое изменение угла за кадр рассчитывается как step * rate. В нашем случае: 1.5 * 0.1 = 0.15 градуса за кадр. Этот механизм позволяет тонко настраивать скорость анимации.
Конфигурация и запуск игры
Стандартная конфигурация игры определяет ее тип, размеры холста, цвет фона и корневой сцены.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
После создания экземпляра Phaser.Game с этой конфигурацией автоматически запускается жизненный цикл сцены: preload, create, а затем циклически update.
Что попробовать дальше
Метод Phaser.Actions.Angle — мощный и лаконичный инструмент для управления углом поворота группы объектов. Он избавляет от необходимости писать циклы в update и централизует логику анимации. Для экспериментов попробуйте изменить второй и третий аргументы функции, чтобы получить разную скорость вращения. Также можно привязать изменение угла не к каждому кадру, а к событию (например, клику мыши), или комбинировать Angle с другими методами из Phaser.Actions, такими как RotateAround для создания орбитального движения.
