О чем этот пример
Работая с текстом в играх, часто нужно знать его точные габариты — для выравнивания, обводки или коллизий. Встроенные методы Phaser для обычного текста здесь не помогут. Эта статья покажет, как правильно получить размеры многострочного BitmapText, используя метод `getTextBounds()`, что позволит вам визуализировать границы текста и точно позиционировать другие игровые объекты относительно него.
Версия 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.bitmapFont('atari', 'assets/fonts/bitmap/atari-smooth.png', 'assets/fonts/bitmap/atari-smooth.xml');
this.load.bitmapFont('gothic', 'assets/fonts/bitmap/gothic.png', 'assets/fonts/bitmap/gothic.xml');
this.load.bitmapFont('hyper', 'assets/fonts/bitmap/hyperdrive.png', 'assets/fonts/bitmap/hyperdrive.xml');
}
create ()
{
const text = this.add.bitmapText(32, 100, 'hyper', 'Arkanoid\nRevenge of Doh', 96);
const graphics = this.add.graphics(0, 0);
const bounds = text.getTextBounds();
graphics.lineStyle(1, 0x00FF00, 1.0);
graphics.strokeRect(bounds.global.x, bounds.global.y, bounds.global.width, bounds.global.height);
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Зачем измерять BitmapText?
В отличие от динамического текста (Text), BitmapText рендерится из заранее подготовленного растрового шрифта. Это делает его отрисовку очень быстрой, но лишает встроенных простых методов для получения размеров, таких как width и height.
Метод getTextBounds() возвращает объект с детальной информацией о фактических границах отрендеренного текста, учитывая переносы строк и межстрочный интервал. Это особенно важно для многострочных надписей, титров или динамически генерируемого текста интерфейса.
Разбор примера: Загрузка и создание текста
В начале примера в методе preload загружаются три растровых шрифта. Обратите внимание на формат: указывается ключ, путь к изображению (png) и путь к файлу описания (xml).
this.load.bitmapFont('atari', 'assets/fonts/bitmap/atari-smooth.png', 'assets/fonts/bitmap/atari-smooth.xml');
В методе create создается сам объект BitmapText. Аргументы конструктора: позиция X, Y, ключ загруженного шрифта, текстовая строка (с символом переноса строки \n) и размер.
const text = this.add.bitmapText(32, 100, 'hyper', 'Arkanoid\nRevenge of Doh', 96);
Важно: размер (96) здесь — это не размер в пикселях, а размер, применяемый к растровому шрифту. Сам шрифт имеет фиксированное разрешение, а этот параметр масштабирует его.
Получение границ и их визуализация
Ключевой вызов — getTextBounds(). Этот метод возвращает объект bounds, содержащий несколько видов границ. В примере используется свойство global, которое содержит итоговые координаты и размеры всего текстового блока на сцене.
const bounds = text.getTextBounds();
Для наглядности полученные границы отрисовываются с помощью графического объекта Graphics. Создается зеленая (0x00FF00) рамка толщиной в 1 пиксель.
const graphics = this.add.graphics(0, 0);
graphics.lineStyle(1, 0x00FF00, 1.0);
graphics.strokeRect(bounds.global.x, bounds.global.y, bounds.global.width, bounds.global.height);
В результате вокруг текста "Arkanoid\nRevenge of Doh" появится зеленый прямоугольник, точно охватывающий обе строки.
Структура объекта bounds
Метод getTextBounds() возвращает объект с несколькими полезными свойствами. global — самый часто используемый.
* bounds.global: Содержит `x,y,width,height` всего текстового блока в координатах сцены.
* bounds.local: Содержит те же параметры, но в локальных координатах относительно позиции самого BitmapText.
* bounds.lines: Массив с данными о каждой строке текста по отдельности.
Использование global идеально подходит для проверки пересечений с другими объектами на сцене или для позиционирования фона.
Что попробовать дальше
Метод getTextBounds() — это надежный способ получить точные размеры BitmapText в Phaser 3. Он решает проблему позиционирования и выравнивания для этого типа объектов.
**Идеи для экспериментов:**
1. Используйте bounds.global для автоматического центрирования текста в середине экрана.
2. Создайте динамическую подложку под текст, размер которой меняется в зависимости от длины строки.
3. Реализуйте простую проверку клика (hit area) по текстовой кнопке, сделанной из BitmapText, сравнивая координаты курсора с bounds.global.
