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

В Phaser загрузка bitmap-шрифтов через отдельные файлы может замедлить старт игры и увеличить количество HTTP-запросов. Этот пример показывает, как упаковать bitmap-шрифт в общий текстурный атлас — популярный инструмент оптимизации графики. Такой подход сокращает количество загружаемых файлов и позволяет эффективнее использовать память, что критично для мобильных и веб-игр.

Версия 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/');
        //  Normal font
        this.load.bitmapFont('chiller', 'assets/fonts/bitmap/chiller.png', 'assets/fonts/bitmap/chiller.xml');

        //  Trimmed Atlas version
        this.load.atlas('fontatlas', 'assets/atlas/chiller.png', 'assets/atlas/chiller.json');
        this.load.xml('chillerXML', 'assets/fonts/bitmap/chiller.xml');
    }

    create ()
    {
        Phaser.GameObjects.BitmapText.ParseFromAtlas(this, 'chiller2', 'fontatlas', 'chiller.png', 'chillerXML');

        this.add.bitmapText(32, 64, 'chiller', '$ Lorem ipsum sit amet');

        //  The texture atlas version
        this.add.bitmapText(32, 64, 'chiller2', '$ Lorem ipsum sit amet');
    }
}

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

const game = new Phaser.Game(config);

Проблема: лишние HTTP-запросы

Обычный способ загрузки bitmap-шрифта в Phaser требует двух файлов: изображения (.png) с символами и XML-файла с их координатами.

Каждый такой файл — отдельный HTTP-запрос, что замедляет загрузку игры, особенно на мобильных устройствах.

this.load.bitmapFont('chiller', 'assets/fonts/bitmap/chiller.png', 'assets/fonts/bitmap/chiller.xml');

Решение: упаковка в Atlas

Текстурный атлас (Atlas) — это одно большое изображение, содержащее множество мелких спрайтов (в нашем случае — символы шрифта), и JSON-файл с координатами каждого спрайта внутри него.

Сначала нужно загрузить сам атлас и отдельно XML-данные шрифта.

this.load.atlas('fontatlas', 'assets/atlas/chiller.png', 'assets/atlas/chiller.json');
this.load.xml('chillerXML', 'assets/fonts/bitmap/chiller.xml');

Создание BitmapText из Atlas

Ключевой метод здесь — Phaser.GameObjects.BitmapText.ParseFromAtlas. Он позволяет создать новый bitmap-шрифт, используя данные из уже загруженного атласа.

Метод принимает: 1. Контекст сцены (this). 2. Ключ для нового шрифта ('chiller2'). 3. Ключ загруженного атласа ('fontatlas'). 4. Имя кадра (frame) внутри атласа, где лежит изображение шрифта ('chiller.png'). 5. Ключ загруженных XML-данных шрифта ('chillerXML').

Phaser.GameObjects.BitmapText.ParseFromAtlas(this, 'chiller2', 'fontatlas', 'chiller.png', 'chillerXML');

Использование оптимизированного шрифта

После парсинга новый шрифт доступен по своему ключу ('chiller2'). Создание текстового объекта с ним ничем не отличается от использования обычного bitmap-шрифта.

В примере создаются два идентичных текстовых объекта для наглядного сравнения.

this.add.bitmapText(32, 64, 'chiller', '$ Lorem ipsum sit amet');
this.add.bitmapText(32, 64, 'chiller2', '$ Lorem ipsum sit amet');

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

Использование ParseFromAtlas — мощный приём для оптимизации загрузки bitmap-шрифтов. Он сокращает количество ресурсов и позволяет шрифту использовать преимущества батчинга текстур внутри атласа. Для экспериментов попробуйте добавить в один атлас несколько разных шрифтов или комбинировать там же спрайты для UI-элементов игры.