О чем этот пример
В разработке игр часто возникает задача анимировать или перемещать группу игровых объектов одновременно. Phaser предоставляет для этого мощный инструмент — `Container`. Эта статья покажет, как использовать контейнер для объединения нескольких анимированных спрайтов и применения к ним комплексных трансформаций одной инструкцией. Вы научитесь создавать сложные составные объекты, что особенно полезно для интерфейсов, боссов или многосоставных персонажей.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.spritesheet('mummy', 'assets/sprites/metalslug_mummy37x45.png', { frameWidth: 37, frameHeight: 45, endFrame: 17 });
}
create ()
{
this.anims.create({
key: 'run',
frames: 'mummy',
frameRate: 20,
repeat: -1
});
const sprite1 = this.add.sprite(100, 200, 'mummy').play('run');
const sprite2 = this.add.sprite(100, 300, 'mummy').play('run');
const sprite3 = this.add.sprite(100, 400, 'mummy').play('run');
const container = this.add.container(300, 0, [ sprite1, sprite2, sprite3 ]);
this.tweens.add({
targets: container,
scaleX: 3,
scaleY: 3,
duration: 6000,
yoyo: true,
repeat: -1
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#010101',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Загрузка ресурсов и создание анимации
Работа начинается с подготовки. В методе preload мы загружаем спрайтшит — набор кадров для анимации. Ключ 'mummy' будет использоваться для ссылки на этот ресурс.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.spritesheet('mummy', 'assets/sprites/metalslug_mummy37x45.png', { frameWidth: 37, frameHeight: 45, endFrame: 17 });
}
Далее, в create, мы создаем анимацию. Указываем ключ 'run', источник кадров (загруженный спрайтшит 'mummy'), частоту смены кадров и параметр бесконечного повтора.
this.anims.create({
key: 'run',
frames: 'mummy',
frameRate: 20,
repeat: -1
});
Создание спрайтов и их анимирование
Теперь создадим три отдельных спрайта, используя текстуру 'mummy'. Сразу после создания каждого спрайта мы запускаем на нем анимацию 'run' с помощью метода .play(). Это позволяет видеть, что каждый мумия 'бежит' независимо.
const sprite1 = this.add.sprite(100, 200, 'mummy').play('run');
const sprite2 = this.add.sprite(100, 300, 'mummy').play('run');
const sprite3 = this.add.sprite(100, 400, 'mummy').play('run');
Обратите внимание, что изначально все спрайты имеют координаты X=100, но разные координаты Y, поэтому они отображаются вертикальным столбцом.
Объединение объектов в контейнер
Вот ключевой шаг. Мы создаем контейнер, передавая ему начальные координаты (300, 0) и массив дочерних объектов — наших трех спрайтов.
const container = this.add.container(300, 0, [ sprite1, sprite2, sprite3 ]);
Контейнер становится родителем для этих спрайтов. Теперь их позиция, масштаб, угол поворота и видимость вычисляются относительно позиции контейнера. Исходные координаты спрайтов (100, 200 и т.д.) становятся их *локальными* координатами внутри контейнера.
Анимация контейнера с помощью Tween
Сила контейнеров проявляется при анимации. Мы создаем твин, который масштабирует весь контейнер по осям X и Y до размера 3 (то есть, в три раза).
this.tweens.add({
targets: container,
scaleX: 3,
scaleY: 3,
duration: 6000,
yoyo: true,
repeat: -1
});
Параметр targets указывает на контейнер. Параметры yoyo: true и repeat: -1 заставляют анимацию плавно возвращаться к исходному масштабу и повторяться бесконечно. В результате все три спрайта масштабируются и двигаются вместе, как единый объект, сохраняя при этом свои индивидуальные анимации.
Настройка игры (Config)
Код завершается стандартной конфигурацией игры Phaser, где указывается наш класс сцены Example.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#010101',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Темный фон (#010101) хорошо контрастирует со спрайтами, делая анимацию четко видимой.
Что попробовать дальше
Контейнеры в Phaser — это простой и эффективный способ группировки игровых объектов для совместного управления. Как показано в примере, вы можете анимировать, перемещать и трансформировать сложные композиции одной командой. Для экспериментов попробуйте: добавить вращение контейнеру с помощью свойства angle, анимировать его позицию `xилиy, динамически добавлять и удалять дочерние объекты методомcontainer.add()` или менять их порядок отрисовки. Это откроет путь к созданию сложных игровых механик.
