О чем этот пример
Визуализация текста в играх — это не только выбор шрифта, но и контроль над его расположением. Особенно важно управлять переносами строк, когда текст должен вписываться в ограниченную область интерфейса, диалогового окна или описания предмета. Phaser предоставляет для этого простой, но мощный инструмент — свойство `maxWidth` для Bitmap Text. В этой статье мы разберем, как с помощью метода `setMaxWidth()` и твинов создать динамический текст, который плавно меняет свою ширину, автоматически перенося строки. Этот прием полезен для анимированных меню, плавного появления текста или создания интерактивных элементов, реагирующих на действия игрока.
Версия 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('desyrel', 'assets/fonts/bitmap/desyrel.png', 'assets/fonts/bitmap/desyrel.xml');
}
create ()
{
const text = "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.";
const b = this.add.bitmapText(0, 0, 'desyrel', text, 32).setMaxWidth(700);
const g = this.add.graphics();
this.tweens.add({
targets: b,
maxWidth: 400,
ease: 'power1',
duration: 5000,
hold: 1000,
yoyo: true,
repeat: -1,
repeatDelay: 1000,
onUpdate: function ()
{
g.clear();
g.fillStyle(0x00ff00, 1);
g.fillRect(b.maxWidth, 0, 2, 600);
}
});
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Создание Bitmap Text с ограничением по ширине
Ключевой объект в примере — Bitmap Text. В отличие от обычного текста, он использует растровый шрифт (загруженный в preload), что дает полный контроль над отображением каждого символа.
Основная магия происходит в методе create. Мы создаем текстовый объект и сразу же устанавливаем для него максимальную ширину в 700 пикселей с помощью метода .setMaxWidth(700). Это значит, что если ширина текстовой строки превысит это значение, Phaser автоматически разобьет ее на несколько строк, соблюдая переносы по словам.
const text = "The sky above the port was the color of television, tuned to a dead channel...";
const b = this.add.bitmapText(0, 0, 'desyrel', text, 32).setMaxWidth(700);
Анимация свойства maxWidth с помощью твинов
Phaser позволяет анимировать не только стандартные свойства вроде `xилиalpha, но и пользовательские, включаяmaxWidth. В примере используется система твинов (this.tweens.add`), чтобы плавно изменять максимальную ширину текста от начального значения до 400 пикселей и обратно.
Конфигурация твина задает:
* Цель анимации (targets: b) — наш текстовый объект.
* Свойство для изменения (maxWidth: 400) — конечное значение ширины.
* Плавность (ease: 'power1') и длительность (duration: 5000).
* Бесконечное повторение с задержкой и режимом «йо-йо» (yoyo: true, repeat: -1), при котором ширина то уменьшается, то возвращается к исходной.
this.tweens.add({
targets: b,
maxWidth: 400,
ease: 'power1',
duration: 5000,
hold: 1000,
yoyo: true,
repeat: -1,
repeatDelay: 1000
});
В результате текст динамически «сжимается» и «расширяется», автоматически перестраивая переносы строк в реальном времени.
Визуализация границы для отладки
Чтобы наглядно видеть, где проходит текущая граница maxWidth, в примере используется объект Graphics (`g). В коллбэкеonUpdate` твина, который вызывается на каждом кадре анимации, мы рисуем вертикальную зеленую линию.
Важные моменты:
1. g.clear() — очищает холст Graphics перед каждой отрисовкой, чтобы линия не оставляла «шлейф».
2. g.fillRect(b.maxWidth, 0, 2, 600) — рисует прямоугольник шириной в 2 пикселя. Его координата `xберется непосредственно из текущего значенияb.maxWidth`, которое в данный момент анимируется твином. Таким образом, линия всегда точно следует за изменяющейся границей текста.
const g = this.add.graphics();
// ... внутри твина:
onUpdate: function ()
{
g.clear();
g.fillStyle(0x00ff00, 1);
g.fillRect(b.maxWidth, 0, 2, 600);
}
Этот прием крайне полезен при отладке и тонкой настройке расположения UI-элементов.
Что попробовать дальше
Метод setMaxWidth() — это простой способ сделать текст в вашей игре адаптивным и визуально аккуратным. Его анимация открывает двери для создания динамичных интерфейсов.
**Идеи для экспериментов:**
1. Привяжите изменение maxWidth к движению мыши или джойстика, чтобы текст «дышал» при наведении.
2. Используйте этот прием для поэтапного, плавного появления длинных диалогов или лора в RPG.
3. Скомбинируйте анимацию ширины с изменением цвета (tint) или масштаба текста для более сложных визуальных эффектов в меню.
