О чем этот пример
TileSprite — это мощный объект Phaser для создания бесшовных текстур, которые можно «прокручивать», что идеально подходит для фонов, анимированных текстур или эффектов параллакса. В этой статье мы разберем, как создавать и анимировать несколько TileSprite, используя один текстурый атлас. Вы научитесь эффективно управлять их положением и создавать сложные визуальные эффекты с минимальным кодом, что особенно полезно для оптимизации игр с большим количеством движущихся элементов.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
iter = 0;
images = [];
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.atlas('atlas', 'assets/atlas/megaset-2.png', 'assets/atlas/megaset-2.json');
}
create ()
{
const frames = [ 'atari400', 'bunny', 'cokecan', 'copy-that-floppy', 'hotdog' ];
for (let i = 0; i < frames.length; ++i)
{
this.images[i] = this.add.tileSprite(i * 160, 0, 160, 600, 'atlas', frames[i]);
this.images[i].originX = 0;
this.images[i].originY = 0;
}
}
update ()
{
let x = 1;
for (let i = 0; i < this.images.length; ++i)
{
this.images[i].tilePositionX += x;
x *= -1;
}
this.iter += 0.01;
}
}
const config = {
type: Phaser.CANVAS,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Загрузка ресурсов: подготовка атласа
Перед созданием спрайтов необходимо загрузить текстуры. В Phaser для этого используется метод preload. В нашем примере загружается один текстурый атлас — это изображение, содержащее множество отдельных кадров (спрайтов) вместе с JSON-файлом, описывающим их координаты.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.atlas('atlas', 'assets/atlas/megaset-2.png', 'assets/atlas/megaset-2.json');
}
Метод setBaseURL задаёт базовый URL для всех последующих загрузок, что удобно, если ресурсы хранятся в одном месте. Затем load.atlas загружает сам атлас: первый аргумент — это ключ 'atlas', по которому мы будем обращаться к атласу в коде, второй — путь к PNG-изображению, третий — путь к JSON-файлу с разметкой.
Создание массива TileSprite
В методе create, который вызывается один раз после загрузки ресурсов, мы создаём пять объектов TileSprite. Каждый из них использует текстуру из загруженного атласа.
const frames = [ 'atari400', 'bunny', 'cokecan', 'copy-that-floppy', 'hotdog' ];
for (let i = 0; i < frames.length; ++i)
{
this.images[i] = this.add.tileSprite(i * 160, 0, 160, 600, 'atlas', frames[i]);
this.images[i].originX = 0;
this.images[i].originY = 0;
}
Метод this.add.tileSprite принимает следующие аргументы: координаты X и Y, ширину, высоту, ключ атласа ('atlas') и имя конкретного кадра из этого атласа (например, 'atari400'). Мы размещаем спрайты по горизонтали с шагом в 160 пикселей (их ширину). Свойства originX и originY устанавливаются в 0 — это меняет точку привязки (origin) спрайта на его левый верхний угол. По умолчанию она находится в центре, но для удобства позиционирования в ряд мы сдвигаем её.
Анимация через смещение тайла
Основная «магия» происходит в методе update, который вызывается на каждом кадре игры. Здесь мы анимируем TileSprite, изменяя свойство tilePositionX.
update ()
{
let x = 1;
for (let i = 0; i < this.images.length; ++i)
{
this.images[i].tilePositionX += x;
x *= -1;
}
this.iter += 0.01;
}
Свойство tilePositionX определяет смещение внутренней текстуры (тайла) по оси X. Увеличивая его, мы создаём эффект плавного движения текстуры вправо, уменьшая — влево. В данном коде используется переменная `x, которая меняет знак на каждой итерации цикла (x *= -1). Это заставляет соседние TileSprite двигаться в противоположных направлениях, создавая интересный волнообразный эффект. Переменнаяiter` в примере увеличивается, но не используется — её можно применить для более сложной логики, например, зависящей от времени.
Конфигурация игры и запуск
Весь пример оборачивается в стандартную конфигурацию Phaser Game.
const config = {
type: Phaser.CANVAS,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Здесь задаются основные параметры: type — рендерер (Canvas), размеры окна, цвет фона, ID HTML-элемента (parent), в который будет встроена игра, и класс сцены. Создание экземпляра new Phaser.Game(config) запускает игровой цикл.
Что попробовать дальше
Использование TileSprite с атласами — это эффективный способ создания динамичных фонов и анимаций с минимальными затратами ресурсов. Вы можете экспериментировать: изменять tilePositionY для вертикального скролла, применять разные скорости для эффекта параллакса, масштабировать тайлы или комбинировать это со свойствами tileScale. Попробуйте загружать отдельные изображения вместо атласа или анимировать спрайты в зависимости от времени, используя переменную iter.
