О чем этот пример
В создании игр текст часто играет ключевую роль — от интерфейсов до диалоговых окон. Но когда текст слишком длинный для вашего дизайна, он может "сломать" визуальную композицию. В Phaser есть два основных типа текста: обычный `Text` и `BitmapText`. В этой статье мы разберем, как эффективно управлять шириной текста, особенно для `BitmapText`, используя метод `setMaxWidth`. Это позволит вам автоматически переносить строки и сохранять текст в заданных границах, что критически важно для создания чистого и профессионального игрового интерфейса.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
preload() {
this.load.bitmapFont('gothic', 'https://labs.phaser.io/assets/fonts/bitmap/gothic.png', 'https://labs.phaser.io/assets/fonts/bitmap/gothic.xml');
}
create() {
this.graphics = this.add.graphics({ x: 0, y: 0, fillStyle: { color: 0xff00ff, alpha: 1 } });
// Text
this.text = this.add.text(100, 100, 'Hello Phaser', { fontFamily: 'Arial Black', fontSize: 32 });
this.text.style.setWordWrapWidth(30);
// Bitmap Text
const bitmapText = this.add.bitmapText(100, 400, 'gothic', 'Hello Phaser', 32);
bitmapText.setMaxWidth(30);
this.bounds2 = bitmapText.getTextBounds(true);
}
update ()
{
this.graphics.clear();
this.graphics.lineStyle(1, 0xff0000, 1);
this.graphics.strokeRectShape(this.text.getBounds());
this.graphics.fillRect(this.bounds2.global.x, this.bounds2.global.y, this.bounds2.global.width, this.bounds2.global.height);
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Два типа текста: Text и BitmapText
Phaser предлагает два класса для работы с текстом: Text и BitmapText. Они имеют разную внутреннюю реализацию и набор методов.
Text использует системные или веб-шрифты и рендерится динамически. Он поддерживает множество стилей и эффектов через CSS. Для управления переносом строк в этом объекте используется метод setWordWrapWidth.
this.text = this.add.text(100, 100, 'Hello Phaser', { fontFamily: 'Arial Black', fontSize: 32 });
this.text.style.setWordWrapWidth(30);
BitmapText использует заранее подготовленные текстовые изображения (bitmap fonts). Это часто дает лучшую производительность и единый визуальный стиль на разных устройствах, но ограничивает в динамических стилях. Для управления шириной в BitmapText используется метод setMaxWidth.
const bitmapText = this.add.bitmapText(100, 400, 'gothic', 'Hello Phaser', 32);
bitmapText.setMaxWidth(30);
Как работает setMaxWidth для BitmapText
Метод setMaxWidth устанавливает максимальную ширину области, в которую должен поместиться текст. Если исходная строка текста (без переносов) превышает эту ширину, Phaser автоматически разбивает текст на несколько строк, используя переносы по словам.
Важно понимать, что значение setMaxWidth задается в пикселях. Это не количество символов, а физическая ширина области отрисовки. Алгоритм переноса пытается разбить строку на слова, которые не превышают эту ширину.
После установки максимальной ширины можно получить новые границы текста с помощью метода getTextBounds. Этот метод возвращает объект с подробными данными, включая конечные размеры текста после переноса.
this.bounds2 = bitmapText.getTextBounds(true);
Аргумент true в getTextBounds указывает, что нужно рассчитать границы немедленно (иногда расчет может быть отложенным).
Визуализация границ текста для понимания
Чтобы точно понять, как текст размещается после применения setMaxWidth, полезно визуализировать его границы. В примере это делается в методе update с помощью объекта Graphics.
Для обычного Text мы получаем его общие геометрические границы методом getBounds и рисуем красный контур.
this.graphics.lineStyle(1, 0xff0000, 1);
this.graphics.strokeRectShape(this.text.getBounds());
Для BitmapText мы используем заранее вычисленные границы (bounds2) и заполняем эту область прямоугольником цвета 0xff00ff.
this.graphics.fillRect(this.bounds2.global.x, this.bounds2.global.y, this.bounds2.global.width, this.bounds2.global.height);
Это позволяет увидеть реальную область, занимаемую текстом после переноса строк, и убедиться, что она соответствует ожидаемой ширине.
Практические советы и важные детали
При использовании setMaxWidth для BitmapText следует учитывать несколько ключевых моментов:
1. **Загрузка шрифта**: BitmapFont должен быть заранее загружен через load.bitmapFont. Шрифт состоит из изображения (.png) и файла данных (.xml), описывающего символы.
this.load.bitmapFont('gothic', 'https://labs.phaser.io/assets/fonts/bitmap/gothic.png', 'https://labs.phaser.io/assets/fonts/bitmap/gothic.xml');
2. **Размер шрифта**: При создании bitmapText вы указываете размер (в примере — 32). Это размер, заданный в данных шрифта, и он влияет на то, как будет рассчитываться ширина.
3. **Обновление текста**: Если вы динамически изменяете текст объекта (например, bitmapText.setText('Новый текст')), перенос строк будет автоматически пересчитан на основе установленной setMaxWidth. Не нужно вызывать метод повторно.
4. **Производительность**: BitmapText обычно рендерится быстрее, чем Text, особенно при большом количестве текстовых элементов. Использование setMaxWidth не добавляет значительных затрат.
Что попробовать дальше
Метод setMaxWidth для BitmapText — это мощный и простой инструмент для контроля над layout текста в вашей игре. Он позволяет автоматически форматировать длинные строки, сохраняя интерфейс чистым и адаптивным. Для экспериментов попробуйте: динамически изменять значение setMaxWidth в ответ на действия игрока (например, при изменении размеров окна); комбинировать перенос строк с другими эффектами BitmapText, такими как окрашивание; сравнить производительность и визуальный результат между Text с setWordWrapWidth и BitmapText с setMaxWidth в сложных сценах.
