О чем этот пример
В разработке игр часто возникает задача перемещать, масштабировать или анимировать несколько игровых объектов одновременно, сохраняя их взаимное расположение. Ручное управление координатами каждого спрайта и текста быстро становится громоздким и подверженным ошибкам. Класс `Container` в Phaser решает эту проблему, позволяя объединять объекты в логическую группу и управлять ею как одним целым. Эта статья покажет, как создать контейнер, поместить в него изображение и текст, а затем применить к нему общее масштабирование и плавную анимацию. Этот подход не только упрощает код, но и повышает его производительность, так как движок оптимизирует отрисовку сгруппированных элементов.
Версия 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.script('webfont', '//ajax.googleapis.com/ajax/libs/webfont/1.4.7/webfont.js');
this.load.image('ball', 'assets/demoscene/doc-ball.png');
}
create ()
{
const container = this.add.container(400, 300);
const ball = this.add.image(0, 0, 'ball');
const text = this.add.text(0, 0, 'Testing');
text.font = 'Arial';
text.setOrigin(0.5, 0.5);
container.add(ball);
container.add(text);
container.setScale(4);
this.tweens.add({
targets: container,
x: container.x + 100,
ease: 'Power1',
duration: 5000,
delay: 500,
yoyo: true,
repeat: -1
});
}
}
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Загрузка ресурсов и инициализация
Подготовка сцены начинается с метода preload. В нем мы загружаем изображение шара и подключаем сторонний скрипт WebFont (хотя в данном примере он не используется напрямую, он демонстрирует возможность загрузки скриптов). Важно указать базовый URL для загрузки ресурсов, чтобы использовать относительные пути.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.script('webfont', '//ajax.googleapis.com/ajax/libs/webfont/1.4.7/webfont.js');
this.load.image('ball', 'assets/demoscene/doc-ball.png');
}
Создание контейнера и добавление объектов
В методе create мы создаем контейнер с центром в точке (400, 300) на сцене. Контейнер сам по себе не имеет графического представления, он служит родительским преобразованием для своих дочерних элементов.
Затем создаются два игровых объекта: изображение шара (ball) и текстовое поле (text). Обратите внимание, что их начальные координаты (0, 0) задаются относительно позиции контейнера. Для текста мы устанавливаем шрифт и меняем его точку привязки (origin) на центр, чтобы он корректно масштабировался и вращался вместе с контейнером.
const container = this.add.container(400, 300);
const ball = this.add.image(0, 0, 'ball');
const text = this.add.text(0, 0, 'Testing');
text.font = 'Arial';
text.setOrigin(0.5, 0.5);
container.add(ball);
container.add(text);
Трансформация контейнера
После добавления объектов в контейнер мы применяем к нему масштабирование с коэффициентом 4. Это увеличивает в четыре раза и шар, и текст, причем их относительное положение и центровка сохраняются. Все трансформации (позиция, масштаб, угол поворота), примененные к контейнеру, автоматически наследуются его детьми.
container.setScale(4);
Анимация контейнера с помощью Tween
Сила контейнеров раскрывается при анимации. Вместо того чтобы создавать отдельные твины для шара и текста, мы анимируем сам контейнер. Твин перемещает контейнер на 100 пикселей вправо по оси X, используя функцию плавности Power1. Анимация длится 5 секунд, начинается с задержкой в 0.5 секунды, а параметры yoyo и repeat заставляют ее бесконечно колебаться туда-обратно.
Поскольку контейнер — это цель анимации (targets), оба его дочерних объекта плавно движутся вместе, сохраняя свою внутреннюю структуру.
this.tweens.add({
targets: container,
x: container.x + 100,
ease: 'Power1',
duration: 5000,
delay: 500,
yoyo: true,
repeat: -1
});
Конфигурация игры
Это стандартная конфигурация для создания экземпляра игры Phaser. Мы используем WebGL-рендерер, устанавливаем размеры холста, цвет фона и указываем, какая сцена (scene) будет использоваться. Ключ parent определяет ID HTML-элемента, в который будет встроен canvas.
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Контейнеры в Phaser — это мощный инструмент для группировки игровых объектов, который значительно упрощает управление сложными композициями и их анимацию. Вместо манипуляций с десятками отдельных свойств вы работаете с одной сущностью.
Для экспериментов попробуйте: добавить в контейнер больше объектов разных типов (частицы, графику), применить к контейнеру вращение (setRotation), анимировать масштаб или альфа-канал, а также вложить один контейнер в другой для создания иерархических структур.
