О чем этот пример
Phaser предоставляет мощный объект `TileSprite` для создания бесшовных текстур и текстурных анимаций, которые часто используются для фонов, крупных объектов и эффектов. Понимание работы с его размерами — ключ к производительности и визуальной точности. В этой статье разберем, как правильно задавать размеры TileSprite, чем отличается явное указание размеров от автоматического, и как это влияет на рендеринг и потребление памяти.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
iter = 0;
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, 500, 500, 'image0');
// this.image0.setAngle(25);
// this.image0.setScale(0.5);
this.image1 = this.add.tileSprite(400, 300, 0, 384, 'image1');
}
update ()
{
// this.image0.tilePositionX = Math.cos(this.iter) * 400;
// this.image0.tilePositionY = Math.sin(this.iter) * 400;
// 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, который позволяет текстуре повторяться (тайлиться) внутри заданной прямоугольной области. В отличие от обычного спрайта, который просто растягивает изображение, TileSprite заполняет область повторяющимися копиями текстуры. Это идеально для создания бесконечных фонов, текстур крупных поверхностей (как трава, вода, кирпичная стена) или анимированных текстурных смещений (параллакс-эффекты).
В примере создаются два TileSprite: один с явными размерами 500x500 пикселей, второй — с шириной 0 и высотой 384 пикселя. Уже на этом этапе видна разница в подходах к определению габаритов объекта.
Явное задание размеров: контроль и производительность
Первый спрайт создается с четко указанными шириной и высотой. Это стандартный и рекомендуемый подход.
this.image0 = this.add.tileSprite(400, 300, 500, 500, 'image0');
Метод this.add.tileSprite(x, y, width, height, textureKey) создает объект с центром в точке (400,300) и размерами 500x500. Текстура 'image0' (изображение Эйнштейна) будет многократно повторена внутри этого прямоугольника. Важно: Phaser создает внутренний буфер (canvas или WebGL texture) именно такого размера — 500x500 пикселей. Это фиксированное потребление памяти, но зато обеспечивает высокую скорость отрисовки, так как тайлинг вычисляется один раз при создании буфера.
Автоматический подбор ширины: удобство с нюансами
Второй спрайт демонстрирует альтернативный подход, где ширина явно не задана.
this.image1 = this.add.tileSprite(400, 300, 0, 384, 'image1');
Здесь ширина указана как `0. В этом случае Phaser автоматически подставляет ширину исходной текстуры'image1'(изображение гриба). Если текстура имеет размер, например, 32x32 пикселя, то итоговая ширинаTileSprite` станет равной 32 пикселям, а высота останется 384. Это удобно для быстрого прототипирования, когда нужно сохранить оригинальную ширину текстуры, но изменить высоту. Однако, если исходная текстура очень большая, это может неожиданно повлиять на размер объекта и потребление памяти. Всегда проверяйте размеры загруженных ассетов.
Манипуляции с TileSprite: поворот, масштаб и смещение тайлов
Код в примере содержит закомментированные строки, которые показывают ключевые возможности TileSprite.
**Поворот и масштабирование всего спрайта:**
// this.image0.setAngle(25);
// this.image0.setScale(0.5);
Методы setAngle() и setScale() работают как с обычными спрайтами, воздействуя на весь объект TileSprite целиком. При этом внутренний тайлинг текстуры сохраняется.
**Анимированное смещение текстуры (тайлов):**
// this.image0.tilePositionX = Math.cos(this.iter) * 400;
// this.image0.tilePositionY = Math.sin(this.iter) * 400;
Свойства tilePositionX и tilePositionY управляют смещением (offset) самой текстуры внутри спрайта. Изменяя их в методе update(), можно создать эффект плавного движения фона (например, бегущей воды или прокручивающегося космоса) без перемещения самого игрового объекта. Это дешевая с точки зрения производительности операция.
Конфигурация сцены и игры: основа для примера
Весь функционал упакован в стандартную конфигурацию Phaser 3.
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Ключевой момент здесь — type: Phaser.WEBGL. TileSprite может работать и в Canvas-режиме, но для сложных тайловых анимаций и лучшей производительности рекомендуется использовать WebGL-рендерер. Класс Example регистрируется как единственная сцена игры. Размеры игрового поля (width, height) задают область, в которой будут отображаться наши спрайты.
Что попробовать дальше
TileSprite — это гибкий инструмент для работы с повторяющимися текстурами. Главный вывод: всегда явно задавайте размеры (width, height), если вам нужен полный контроль над производительностью и визуальным результатом. Используйте автоматический подбор ширины (через `0) с осторожностью, зная размеры своей текстуры. Для экспериментов попробуйте раскомментировать код вupdate()и создать циклическую анимацию движения фона, поиграйте сtileScaleX/Yдля зуммирования самой текстуры или комбинируйте несколькоTileSprite` для создания сложных параллакс-слоев.
