О чем этот пример

Дизайн пользовательского интерфейса в играх часто требует элементов, которые должны растягиваться под разный контент без потери качества. Кнопки, панели, диалоговые окна — всё это должно выглядеть чётко при любых размерах. В Phaser для решения этой задачи существует мощный инструмент — объект Nine Slice. Эта статья покажет, как с его помощью создавать адаптивные UI-элементы из одного изображения, экономя ресурсы и время разработки.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.atlas('buttons', 'assets/ui/nine-slice.png', 'assets/ui/nine-slice.json');
    }

    create ()
    {
        this.add.nineslice(400, 300, 'buttons', 'blue-box', 600, 400, 16, 16, 32, 16);

        this.add.nineslice(400, 300, 'buttons', 'button-bg', 400, 110, 64, 64);
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#000000',
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Что такое Nine Slice?

Nine Slice (или 9-slice scaling) — это техника масштабирования растрового изображения, при которой оно делится на девять частей: четыре угла, четыре стороны и центральная область. Углы остаются неизменными, стороны растягиваются только по одной оси, а центр растягивается по обеим осям. Это позволяет создавать элементы интерфейса (например, кнопки или панели) любого размера без видимых искажений по краям.

В Phaser для работы с этой техникой используется фабрика игровых объектов this.add.nineslice().

Загрузка исходного атласа

Перед созданием объекта необходимо загрузить текстуру. В примере используется атлас — изображение, содержащее несколько спрайтов, и JSON-файл с координатами.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.atlas('buttons', 'assets/ui/nine-slice.png', 'assets/ui/nine-slice.json');

Метод this.load.atlas() загружает изображение nine-slice.png и данные из nine-slice.json. Ключ 'buttons' — это идентификатор, по которому мы будем обращаться к этому атласу в сцене. Установка базового URL упрощает загрузку ресурсов с удалённого сервера.

Создание первого Nine Slice объекта

Рассмотрим первый вызов фабрики. Он создаёт синюю панель.

this.add.nineslice(400, 300, 'buttons', 'blue-box', 600, 400, 16, 16, 32, 16);

Метод принимает несколько аргументов: 1. 400, 300 — координаты X и Y центра объекта на экране. 2. 'buttons' — ключ загруженного атласа. 3. 'blue-box' — имя фрейма (спрайта) внутри атласа, который будет использован как исходное изображение. 4. 600, 400 — итоговая ширина и высота создаваемого объекта. 5. 16, 16, 32, 16 — параметры срезов (slice). Это самые важные числа. Они определяют, как изображение будет разделено на девять частей. Разберём их подробнее в следующем разделе.

Как работают параметры срезов

Параметры срезов определяют размеры неизменяемых областей изображения.

// Аргументы после размеров: leftWidth, rightWidth, topHeight, bottomHeight
this.add.nineslice(x, y, atlas, frame, width, height, 16, 16, 32, 16);

* leftWidth: 16 — ширина левой вертикальной полосы (она не будет растягиваться по оси X). * rightWidth: 16 — ширина правой вертикальной полосы. * topHeight: 32 — высота верхней горизонтальной полосы (не растягивается по оси Y). * bottomHeight: 16 — высота нижней горизонтальной полосы.

Эти значения "вырезают" из исходного изображения blue-box углы и стороны. Всё, что находится между этими областями (центр), будет растянуто до нужных размеров (600x400). Например, левый верхний угол — это прямоугольник 16x32 пикселя, взятый из исходного спрайта.

Создание кнопки с упрощённым синтаксисом

Второй вызов демонстрирует упрощённый синтаксис, который работает, если все четыре среза имеют одинаковый размер.

this.add.nineslice(400, 300, 'buttons', 'button-bg', 400, 110, 64);

Здесь указан только один параметр среза — 64. Phaser интерпретирует это как leftWidth = rightWidth = topHeight = bottomHeight = 64. Это удобно для квадратных симметричных текстур, где все рамки одинаковы. Объект создастся с размерами 400x110 пикселей, а его углы и края останутся чёткими.

Что попробовать дальше

Объект Nine Slice — незаменимый инструмент для построения гибкого и производительного интерфейса в Phaser. Он позволяет использовать одну текстуру для элементов множества размеров, что сокращает объём графических ресурсов. Для экспериментов попробуйте изменить параметры срезов в реальном времени, чтобы увидеть, как они влияют на итоговое изображение, или анимируйте изменение ширины и высоты объекта, создавая плавно расширяющиеся панели.