О чем этот пример
В разработке игр часто требуются интерфейсные элементы, которые могут плавно менять размер без искажения текстуры. Техника Nine Slice (или 9-сегментное растяжение) решает эту проблему, позволяя создавать кнопки, панели и другие UI-элементы, которые сохраняют чёткие углы и границы при любых размерах. В этой статье мы разберём практический пример из официальной документации Phaser, покажем как работает Nine Slice и как анимировать такие элементы для создания динамичного интерфейса.
Версия 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('ui', 'assets/ui/nine-slice.png', 'assets/ui/nine-slice.json');
}
create ()
{
const button1 = this.add.nineslice(0, 100, 'ui', 'button-bg', 128, 110, 64, 64).setOrigin(0, 0.5);
const button2 = this.add.nineslice(400, 300, 'ui', 'button-bg', 128, 110, 64, 64);
const button3 = this.add.nineslice(800, 500, 'ui', 'button-bg', 128, 110, 64, 64).setOrigin(1, 0.5);
this.tweens.add({
targets: [ button1, button2, button3 ],
width: 700,
duration: 3000,
ease: 'sine.inout',
yoyo: true,
repeat: -1,
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#7b0046',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое Nine Slice и зачем он нужен
Nine Slice — это техника разделения текстуры на 9 частей: 4 угла, 4 стороны и центральная часть. Углы остаются неизменными при масштабировании, стороны растягиваются только по одной оси, а центр — по обеим. Это идеально подходит для кнопок, окон диалогов, панелей здоровья — любых элементов, где важны чёткие границы.
В Phaser реализация доступна через метод this.add.nineslice(). В примере используется текстура кнопки, которая корректно масштабируется по ширине от 128 до 700 пикселей, сохраняя скруглённые углы.
Загрузка ресурсов: Атлас текстур
Перед созданием кнопок необходимо загрузить текстуру и данные атласа. В методе preload() используется this.load.atlas(), который загружает изображение и JSON-файл с координатами фреймов.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.atlas('ui', 'assets/ui/nine-slice.png', 'assets/ui/nine-slice.json');
}
Метод setBaseURL() задаёт базовый URL для всех последующих загрузок. Это удобно, если все ресурсы лежат в одной директории. Ключ 'ui' — это идентификатор, по которому мы обращаемся к атласу в коде. Фрейм 'button-bg' внутри этого атласа содержит текстуру для нашей кнопки.
Создание кнопок с разными точками отсчёта
В методе create() создаются три кнопки с помощью this.add.nineslice(). Параметры метода определяют позицию, текстуру и логику масштабирования.
const button1 = this.add.nineslice(0, 100, 'ui', 'button-bg', 128, 110, 64, 64).setOrigin(0, 0.5);
const button2 = this.add.nineslice(400, 300, 'ui', 'button-bg', 128, 110, 64, 64);
const button3 = this.add.nineslice(800, 500, 'ui', 'button-bg', 128, 110, 64, 64).setOrigin(1, 0.5);
Разберём параметры по порядку:
1. 0, 100 — координаты X и Y на сцене.
2. 'ui' — ключ атласа, загруженного в preload().
3. 'button-bg' — имя фрейма внутри атласа.
4. 128 — начальная ширина объекта.
5. 110 — начальная высота объекта.
6. 64, 64 — размер левого/верхнего и правого/нижнего срезов (в пикселях). Эти значения определяют, какие области текстуры являются углами и не будут растягиваться.
Метод setOrigin() меняет точку привязки (origin) объекта. Для button1 это (0, 0.5) — левый край по центру по вертикали, поэтому кнопка будет растягиваться вправо. Для button3 — (1, 0.5) (правый край), поэтому анимация ширины будет идти влево. button2 использует стандартный origin (0.5, 0.5) — центр.
Анимация ширины с помощью Tween
Чтобы продемонстрировать работу Nine Slice, к кнопкам применяется анимация изменения ширины. Phaser предоставляет мощную систему твинов через this.tweens.add().
this.tweens.add({
targets: [ button1, button2, button3 ],
width: 700,
duration: 3000,
ease: 'sine.inout',
yoyo: true,
repeat: -1,
});
Конфигурация твина:
- targets: массив объектов, к которым применяется анимация.
- width: 700 — целевое значение свойства width.
- duration: 3000 — длительность анимации в миллисекундах (3 секунды).
- ease: 'sine.inout' — функция плавности, создающая мягкий старт и остановку.
- yoyo: true — после достижения цели анимация проигрывается в обратном порядке.
- repeat: -1 — бесконечное повторение всей последовательности (вперёд-назад).
Именно здесь видна магия Nine Slice: несмотря на радикальное изменение ширины, скруглённые углы и градиенты кнопок остаются идеальными.
Что попробовать дальше
Nine Slice — это незаменимый инструмент для создания гибкого и визуально consistent игрового интерфейса в Phaser. Он избавляет от необходимости готовить отдельные текстуры для каждого размера кнопки. Для экспериментов попробуйте: изменить параметры срезов (например, 32, 32), анимировать высоту вместо ширины, привязать к кнопкам текст или иконки, используя их как контейнеры, или создать сложную панель HUD с несколькими Nine Slice-элементами.
