О чем этот пример
Вы когда-нибудь сталкивались с тем, что длинный текст в вашей игре на Phaser вылезает за границы экрана или элемента интерфейса? Это распространённая проблема, особенно для локализаций или динамически генерируемых сообщений. К счастью, в Phaser есть встроенный механизм для автоматического переноса слов. В этой статье мы разберём, как правильно его настроить, чтобы текст всегда красиво умещался в отведённое пространство, улучшая читаемость и общий вид вашей игры.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
}
create ()
{
var messages = [ 'Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet Lorem ipsum dolor sit amet', 'Test 1', 'Test 2', 'Test 3' ];
var textStyle = {
wordWrap: { width: 385, useAdvancedWrap: true }
};
var text = this.add.text(0, 0, '', textStyle);
text.setText(messages.join('\n'));
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
backgroundColor: '#2d2d6d',
scene: Example
};
const game = new Phaser.Game(config);
Проблема: Текст за пределами экрана
Представьте, что вы создаёте диалоговую систему или информационную панель. Если текстовая строка окажется слишком длинной, она попросту уйдёт за границы вашего игрового мира или контейнера, и игрок не увидит её полностью. В предоставленном примере массив messages содержит как очень длинную строку, так и короткие. Без специальной обработки длинная строка отобразится в одну линию, что явно не то, что нужно.
Именно для решения этой проблемы в объекте TextStyle существует опция wordWrap.
Решение: Настройка объекта wordWrap
Ключ к управлению переносом слов лежит в конфигурации стиля текста. Вместо того чтобы передавать простую строку стиля (например, { fontSize: '16px' }), мы создаём объект с вложенным свойством wordWrap.
var textStyle = {
wordWrap: { width: 385, useAdvancedWrap: true }
};
Здесь мы определяем два параметра:
1. width: 385 — Это максимальная ширина в пикселях, которую может занимать одна строка текста. Как только текст достигает этой границы, происходит перенос.
2. useAdvancedWrap: true — Этот флаг включает более интеллектуальный алгоритм переноса, который корректно обрабатывает пробелы и стремится разбивать строки по границам слов, а не просто по достижении лимита символов.
Этот объект стиля затем передаётся третьим аргументом в метод this.add.text().
Создание и наполнение текстового объекта
Теперь создадим сам текстовый объект, используя подготовленный стиль.
var text = this.add.text(0, 0, '', textStyle);
Мы указываем начальные координаты (0, 0), пустую начальную строку и наш стиль textStyle. Важно сначала создать объект с правильными настройками, а уже потом наполнять его контентом.
Для установки текста используем метод setText(). В примере все строки из массива объединяются в одну с помощью join('\n'), где '\n' — символ новой строки. Это означает, что каждая строка массива станет новым абзацем, и к каждой из них (в частности, к длинной первой) будет применено правило переноса.
text.setText(messages.join('\n'));
Как это работает на практике
После запуска примера вы увидите, что длинная строка "Lorem ipsum..." разбита на несколько строк. Каждая из этих строк не превышает заданную ширину в 385 пикселей. Короткие строки "Test 1", "Test 2" и "Test 3" остаются в одну строку, так как они и так умещаются в лимит.
Механизм переноса работает в реальном времени. Если вы динамически измените текст с помощью setText(), новый контент также будет автоматически отформатирован согласно правилам wordWrap. Это особенно полезно для обновляемого текста, например, логов событий или подсказок.
Что попробовать дальше
Использование wordWrap — это простой и мощный способ контролировать вёрстку текста в ваших играх на Phaser. Он избавляет от необходимости вручную разбивать строки и делает интерфейс более адаптивным.
**Идеи для экспериментов:**
1. Попробуйте менять значение width в процессе игры, чтобы текст динамически подстраивался под изменяющиеся размеры панели.
2. Поэкспериментируйте с useAdvancedWrap: false и посмотрите, как изменится поведение переноса.
3. Скомбинируйте перенос слов с другими свойствами TextStyle, такими как align (выравнивание) или lineSpacing (межстрочный интервал), для создания сложных текстовых блоков.
