О чем этот пример
Статичные фоны — это скучно. В мире игр оживить задний план — значит погрузить игрока в атмосферу. Phaser предлагает мощный, но простой инструмент для этого — объект TileSprite. Эта статья покажет, как использовать его свойства `tilePosition` и `tileScale` для создания динамических, бесшовно зацикленных анимаций. Вы научитесь превращать обычную картинку в движущийся фон или вращающийся спрайт, что идеально подходит для параллакс-эффектов, анимированных текстур воды, огня или магических полей.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
iter = 0;
tween;
image1;
image0;
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('image0', 'assets/pics/ra-einstein.png');
this.load.image('image1', 'assets/sprites/mushroom2.png');
}
create ()
{
this.image0 = this.add.tileSprite(400, 300, 800, 600, 'image0');
this.image1 = this.add.tileSprite(400, 300, 250, 250, 'image1');
this.tween = this.tweens.addCounter({
from: 1,
to: 2,
duration: 5000,
ease: 'Sine.easeInOut',
yoyo: true,
repeat: -1
});
}
update ()
{
this.image0.tilePositionX = Math.cos(this.iter) * 700;
this.image0.tilePositionY = Math.sin(this.iter) * 500;
this.image0.tileScaleX = this.tween.getValue();
this.image0.tileScaleY = this.tween.getValue();
this.image1.tilePositionX = Math.cos(-this.iter) * 400;
this.image1.tilePositionY = Math.sin(-this.iter) * 400;
this.iter += 0.01;
}
}
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое TileSprite и зачем он нужен
TileSprite — это особый игровой объект в Phaser, который отображает текстуру с возможностью тайлинга (повторения). В отличие от обычного Sprite, его изображение не обрезается под размер объекта, а бесшовно заполняет отведённую область, как плитка. Это ключевое свойство позволяет сдвигать (tilePosition) и масштабировать (tileScale) саму текстуру внутри контейнера, создавая иллюзию движения или деформации.
Основное применение — создание больших, бесшовно движущихся фонов без необходимости загружать огромные изображения. В примере мы создадим два таких объекта: один на весь экран с портретом, другой — поменьше, со спрайтом гриба.
Создание и настройка TileSprite
Объекты создаются в методе create сцены. Метод this.add.tileSprite принимает координаты (x, y), ширину, высоту и ключ загруженного изображения.
this.image0 = this.add.tileSprite(400, 300, 800, 600, 'image0');
this.image1 = this.add.tileSprite(400, 300, 250, 250, 'image1');
Первый спрайт (image0) растягивается на весь экран (800x600), второй (image1) — это меньший квадрат по центру. Оба используют разные текстуры. Важно: исходные изображения должны быть либо бесшовными, либо такими, где шов не будет заметен при повторении.
Анимация смещения текстуры (tilePosition)
Динамика достигается за счёт изменения свойств tilePositionX и tilePositionY в методе update. Эти свойства сдвигают текстуру по соответствующим осям. В примере для расчёта смещения используются тригонометрические функции Math.cos и Math.sin, что создаёт плавное круговое движение.
this.image0.tilePositionX = Math.cos(this.iter) * 700;
this.image0.tilePositionY = Math.sin(this.iter) * 500;
this.image1.tilePositionX = Math.cos(-this.iter) * 400;
this.image1.tilePositionY = Math.sin(-this.iter) * 400;
this.iter += 0.01;
Переменная iter увеличивается каждый кадр, меняя аргумент для функций. Умножение на разные числа (700, 500, 400) задаёт амплитуду (радиус) движения. Знак -this.iter для image1 заставляет текстуру двигаться в противоположную сторону, создавая интересный визуальный контраст.
Плавное масштабирование текстуры (tileScale) с помощью Tween
Свойства tileScaleX и tileScaleY управляют масштабом тайлированной текстуры. Значение 1 — исходный размер, 2 — увеличение в два раза. Для плавной анимации масштаба используется система Tween. В create создаётся счётчик (tweens.addCounter), который циклически меняет значение от 1 до 2 и обратно.
this.tween = this.tweens.addCounter({
from: 1,
to: 2,
duration: 5000,
ease: 'Sine.easeInOut',
yoyo: true,
repeat: -1
});
Затем в update текущее значение этого твина присваивается свойствам масштаба.
this.image0.tileScaleX = this.tween.getValue();
this.image0.tileScaleY = this.tween.getValue();
Это заставляет текстуру image0 равномерно "дышать", плавно увеличиваясь и уменьшаясь. Параметры yoyo: true и repeat: -1 обеспечивают бесконечное повторение цикла.
Что попробовать дальше
TileSprite — это ваш инструмент для оживления игрового мира без чрезмерных затрат ресурсов. Комбинируя анимацию позиции и масштаба, можно создавать сложные эффекты. Для экспериментов попробуйте: привязать tilePosition к скорости игрока для параллакса, использовать разные easing-функции для твинов, анимировать tileScaleX и tileScaleY независимо для эффекта сжатия или наложить на TileSprite маску для создания анимированных порталов.
