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

Работая с текстом в играх, часто нужно знать его точные габариты — для выравнивания, обводки или коллизий. Встроенные методы 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.