О чем этот пример
Отображение больших текстовых блоков — частая задача при создании игровых интерфейсов: диалоги, описания, лоры. Phaser позволяет сделать это буквально в одну строку, передав массив строк в метод `add.text`. В этой статье разберем, как это работает на практическом примере и как избежать типичных ошибок.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
const content = [
'The sky above the port was the color of television, tuned to a dead channel.',
'`It\'s not like I\'m using,\' Case heard someone say, as he shouldered his way ',
'through the crowd around the door of the Chat. `It\'s like my body\'s developed',
'this massive drug deficiency.\' It was a Sprawl voice and a Sprawl joke.',
'The Chatsubo was a bar for professional expatriates; you could drink there for',
'a week and never hear two words in Japanese.',
'',
'Ratz was tending bar, his prosthetic arm jerking monotonously as he filled a tray',
'of glasses with draft Kirin. He saw Case and smiled, his teeth a webwork of',
'East European steel and brown decay. Case found a place at the bar, between the',
'unlikely tan on one of Lonny Zone\'s whores and the crisp naval uniform of a tall',
'African whose cheekbones were ridged with precise rows of tribal scars. `Wage was',
'in here early, with two joeboys,\' Ratz said, shoving a draft across the bar with',
'his good hand. `Maybe some business with you, Case?\'',
'',
'Case shrugged. The girl to his right giggled and nudged him.',
'The bartender\'s smile widened. His ugliness was the stuff of legend. In an age of',
'affordable beauty, there was something heraldic about his lack of it. The antique',
'arm whined as he reached for another mug.',
'',
'',
'From Neuromancer by William Gibson'
];
this.add.text(100, 100, content, { fontFamily: 'Arial', color: '#00ff00' });
}
}
const config = {
type: Phaser.CANVAS,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка данных: массив строк
Вместо того чтобы склеивать текст в одну огромную строку с символами переноса \n, Phaser позволяет использовать обычный массив. Каждый элемент массива станет новой строкой в отображаемом тексте. Это упрощает форматирование и редактирование.
Пустые строки в массиве (как '' в примере) создают вертикальные отступы, что полезно для разделения абзацев.
const content = [
'Первая строка первого абзаца.',
'Вторая строка первого абзаца.',
'', // Пустая строка создаст отступ между абзацами
'Первая строка второго абзаца.'
];
Создание текстового объекта
Основная работа выполняется методом this.add.text(x, y, content, style). В качестве третьего аргумента content можно передать как строку, так и массив строк. Phaser автоматически интерпретирует массив.
Ключевые параметры:
* x, y — координаты верхнего левого угла текстового блока.
* content — наш подготовленный массив строк.
* style — объект со стилями. В примере заданы только шрифт и цвет, но доступно множество других опций.
this.add.text(100, 100, content, { fontFamily: 'Arial', color: '#00ff00' });
Настройка внешнего вида (стилизация)
Объект стиля — мощный инструмент. Помимо цвета и шрифта, можно задать размер, жирность, тень, обводку и многое другое. Важно помнить, что стиль применяется ко всему текстовому объекту целиком.
// Расширенный пример объекта стиля
const textStyle = {
fontFamily: 'Courier New',
fontSize: '18px',
color: '#ffffff', // Белый цвет
backgroundColor: '#5d5d5d', // Серый фон за текстом
padding: { x: 10, y: 5 }, // Внутренние отступы фона
stroke: '#000000', // Цвет обводки букв
strokeThickness: 3 // Толщина обводки
};
this.add.text(200, 300, content, textStyle);
Важные нюансы и производительность
1. **Динамическое обновление:** Созданный текстовый объект (GameObject) имеет метод setText. Ему также можно передать массив для обновления содержимого на лету.
const myText = this.add.text(100, 100, content, style);
// Позже, в ответ на событие игры:
const newContent = ['Новый', 'многострочный', 'текст'];
myText.setText(newContent);
2. **Производительность:** Создание одного объекта с многострочным текстом эффективнее, чем создание множества отдельных текстовых объектов для каждой строки. Это уменьшает количество отрисовываемых элементов (draw calls).
Что попробовать дальше
Использование массива строк для многострочного текста в Phaser — это чистый, удобочитаемый и производительный подход. Он отлично подходит для статического контента вроде титров или описаний.
**Идеи для экспериментов:**
1. Реализуйте плавное появление диалога по строкам, используя setText в таймере.
2. Создайте текстовый журнал квеста, добавляя новые записи в массив и обновляя объект текста.
3. Скомбинируйте этот метод с Bitmap-шрифтами (BitmapText) для создания стилизованных диалоговых окон пиксель-арт игры.
