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

Визуальный стиль — ключевой элемент игровой атмосферы. Использование ретро-шрифтов позволяет мгновенно погрузить игрока в ностальгическую эстетику 8-битных или 16-битных аркад. Эта статья покажет, как создать динамически обновляемый текст с пиксельным шрифтом, который идеально подходит для отображения очков, таймеров или версий игры. Вы научитесь загружать растровый шрифт, настраивать его и управлять им в реальном времени.

Версия 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.image('knighthawks', 'assets/fonts/retro/knight3.png');
        this.value = 0;
    }

    create ()
    {
        var config = {
            image: 'knighthawks',
            width: 31,
            height: 25,
            chars: Phaser.GameObjects.RetroFont.TEXT_SET6,
            charsPerRow: 10,
            spacing: { x: 1, y: 1 }
        };

        this.cache.bitmapFont.add('knighthawks', Phaser.GameObjects.RetroFont.Parse(this, config));

        this.dynamic = this.add.bitmapText(0, 200, 'knighthawks', 'PHASER 3');

        this.dynamic.setScale(3);
    }

    update ()
    {
        this.dynamic.text = 'VER ' + this.value.toFixed(2);
        this.value += 0.01;
    }
}

const config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    pixelArt: true,
    scene: Example
};

const game = new Phaser.Game(config);

Загрузка ресурсов и подготовка сцены

Сцена начинается с метода preload. Здесь мы задаем базовый URL для загрузки ресурсов и загружаем изображение, которое содержит все символы нашего будущего шрифта — спрайтшит.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('knighthawks', 'assets/fonts/retro/knight3.png');
    this.value = 0;
}
Ключевые моменты:
*   `this.load.setBaseURL()` устанавливает корневой путь для всех последующих загрузок, что упрощает указание относительных путей.
*   `this.load.image()` загружает PNG-изображение `knight3.png` и присваивает ему ключ `'knighthawks'` для дальнейшего использования.
*   `this.value = 0` инициализирует переменную, которая будет использоваться для анимации текста в методе `update`.

Создание растрового шрифта из изображения

Вся магия происходит в методе create. Мы не можем использовать загруженную картинку как шрифт напрямую. Сначала нужно объяснить движку, как это изображение устроено — из каких символов оно состоит и как они расположены.

var config = {
    image: 'knighthawks',
    width: 31,
    height: 25,
    chars: Phaser.GameObjects.RetroFont.TEXT_SET6,
    charsPerRow: 10,
    spacing: { x: 1, y: 1 }
};

Конфигурационный объект config содержит все необходимые параметры для парсинга: * image: ключ загруженного изображения. * width и height: размер (в пикселях) одного символа на спрайтшите. * chars: строка, определяющая набор символов. Мы используем встроенную константу TEXT_SET6, которая содержит цифры, буквы и основные знаки препинания. * charsPerRow: количество символов в одной строке на изображении. Это нужно для правильного расчета координат. * spacing: отступы между символами на самом изображении.

Теперь нужно обработать эту конфигурацию и добавить шрифт в кеш движка.

this.cache.bitmapFont.add('knighthawks', Phaser.GameObjects.RetroFont.Parse(this, config));

* Phaser.GameObjects.RetroFont.Parse() — статический метод, который анализирует изображение на основе переданной конфигурации и возвращает данные, готовые для использования как шрифт. * this.cache.bitmapFont.add() сохраняет эти данные в кеш под тем же ключом 'knighthawks'. Теперь этот ключ можно использовать для создания объектов BitmapText.

Создание и настройка текстового объекта

После регистрации шрифта в кеше можно создавать текстовые объекты. Это делается с помощью фабричного метода сцены add.bitmapText.

this.dynamic = this.add.bitmapText(0, 200, 'knighthawks', 'PHASER 3');
this.dynamic.setScale(3);
*   `this.add.bitmapText(x, y, font, text)` создает объект растрового текста. Мы указываем начальные координаты (0, 200), ключ шрифта `'knighthawks'` и начальный текст `'PHASER 3'`.
*   `this.dynamic.setScale(3)` увеличивает размер текста в 3 раза. Поскольку это растровый шрифт, масштабирование сохранит четкие пиксельные границы, что критически важно для ретро-стиля. Объект сохраняется в свойство `this.dynamic` для последующего обновления.

Динамическое обновление текста

Игровые механики часто требуют обновления текста в реальном времени: счет, время, уровень здоровья. Для этого используется метод update, который вызывается на каждом кадре игры.

update ()
{
    this.dynamic.text = 'VER ' + this.value.toFixed(2);
    this.value += 0.01;
}
*   `this.dynamic.text = ...` — мы напрямую присваиваем новое значение свойству `.text` нашего объекта `BitmapText`. Движок автоматически перерисует текст с новым содержимым.
*   `this.value.toFixed(2)` форматирует число, увеличивающееся на 0.01 каждый кадр, до двух знаков после запятой, создавая эффект плавно возрастающего числового значения (например, 'VER 1.23').
*   Это наглядная демонстрация, как можно связать игровую логику (например, счетчик времени) с визуальным представлением.

Что попробовать дальше

BitmapText в Phaser 3 — это мощный и производительный инструмент для работы с текстом в пиксельном стиле. Вы научились создавать шрифт из спрайтшита, настраивать его параметры и динамически менять отображаемый текст в игровом цикле. Чтобы закрепить знания, попробуйте: 1. Использовать другой спрайтшит и подобрать для него параметры width, height и charsPerRow. 2. Сделать текст, который следует за курсором мыши, обновляя его координаты в update. 3. Связать значение this.value не с временем, а, например, с расстоянием до какого-либо объекта в игре.