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

Современные игры требуют высококачественной графики, которая может существенно увеличить размер загружаемых ресурсов и время запуска. Phaser 3 предоставляет мощный механизм загрузки сжатых текстур, позволяя использовать аппаратное ускорение и экономить трафик. Эта статья покажет, как загружать текстуры в разных форматах сжатия (ASTC, ETC, PVRTC, S3TC) в зависимости от платформы и браузера, автоматически выбирая оптимальный вариант. Это критически важно для мобильных и веб-приложений, где каждый килобайт на счету.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Demo extends Phaser.Scene
{
    constructor ()
    {
        super();
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.texture('labs', {
            'ASTC': 'assets/compressed/compressed/labs-ASTC-4x4-lRGB.pvr',
            'ETC': 'assets/compressed/compressed/labs-ETC2-lRGB.pvr',
            'PVRTC': 'assets/compressed/compressed/labs-PVRTC-4BPP-lRGB.pvr',
            'S3TC': 'assets/compressed/compressed/labs-S3TC-BC3-lRGB.pvr',
            'IMG': 'assets/compressed/uncompressed/labs.png'
        });
    }

    create ()
    {
        const logo = this.add.image(400, 300, 'labs');

        this.add.text(400, 570, logo.frame.source.compressionAlgorithm).setOrigin(0.5, 0);
    }
}

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    backgroundColor: '#2d2d6d',
    scene: Demo
};

const game = new Phaser.Game(config);

Настройка базового URL и загрузка текстур

Перед загрузкой ресурсов полезно установить базовый URL, чтобы не указывать полный путь для каждого файла. Это особенно удобно при работе с внешними репозиториями или CDN.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');

Ключевой метод для загрузки сжатых текстур — load.texture. Вместо передачи одного пути к файлу, мы передаем объект, где ключи — это названия форматов сжатия, а значения — пути к соответствующим файлам. Phaser автоматически определит, какой формат поддерживается текущей средой выполнения (браузером или платформой), и загрузит оптимальную версию. В примере также указан путь к несжатому PNG-файлу (IMG) в качестве фолбэка.

this.load.texture('labs', {
    'ASTC': 'assets/compressed/compressed/labs-ASTC-4x4-lRGB.pvr',
    'ETC': 'assets/compressed/compressed/labs-ETC2-lRGB.pvr',
    'PVRTC': 'assets/compressed/compressed/labs-PVRTC-4BPP-lRGB.pvr',
    'S3TC': 'assets/compressed/compressed/labs-S3TC-BC3-lRGB.pvr',
    'IMG': 'assets/compressed/uncompressed/labs.png'
});

Создание изображения и получение информации о сжатии

После загрузки текстуры в методе create мы можем использовать её так же, как и обычное изображение. Текстура доступна по своему ключу, в данном случае 'labs'.

const logo = this.add.image(400, 300, 'labs');

Каждый кадр (frame) текстуры содержит свойство source, которое хранит информацию об источнике изображения. Свойство source.compressionAlgorithm — это строка, указывающая, какой именно алгоритм сжатия был выбран и загружен Phaser. Это очень полезно для отладки и логирования.

this.add.text(400, 570, logo.frame.source.compressionAlgorithm).setOrigin(0.5, 0);

Мы создаем текстовый объект и позиционируем его внизу экрана, выводя название использованного алгоритма. Метод setOrigin(0.5, 0) устанавливает точку привязки текста по центру по горизонтали и по верхнему краю по вертикали, что удобно для выравнивания.

Конфигурация игры и запуск сцены

Конфигурационный объект игры определяет основные параметры, такие как тип рендерера, размеры холста и стартовую сцену. В данном примере используется фон темно-синего цвета для контраста с логотипом.

const config = {
    type: Phaser.AUTO, // Phaser выберет WebGL или Canvas автоматически
    parent: 'phaser-example', // ID DOM-элемента для встраивания
    width: 800,
    height: 600,
    backgroundColor: '#2d2d6d',
    scene: Demo // Указываем класс нашей сцены
};

Инициализация игры происходит путем создания нового экземпляра класса Phaser.Game с передачей конфигурационного объекта. Это точка входа для всего приложения.

const game = new Phaser.Game(config);

Почему это работает: автоматический выбор формата

Phaser использует внутреннюю систему определения возможностей браузера. Разные форматы сжатия имеют разную поддержку: - **S3TC (BC3/DXT5)**: Широко поддерживается на desktop в Chrome, Firefox, Edge. - **PVRTC**: Характерен для устройств Apple (iOS, Safari на macOS). - **ETC2**: Стандартный формат для OpenGL ES 3.0 (многие современные Android-устройства и WebGL 2.0). - **ASTC**: Современный эффективный формат, поддерживаемый многими мобильными GPU и WebGL 2.0.

Передавая объект с вариантами, вы делегируете Phaser ответственность за выбор самого производительного и поддерживаемого формата. Если ни один аппаратный формат не поддерживается, загрузится фолбэк-изображение (IMG), что гарантирует работоспособность в любой среде.

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

Использование сжатых текстур в Phaser 3 — это простой и эффективный способ оптимизации размера ресурсов и скорости загрузки вашей игры без потери качества. Механизм автоматического выбора формата избавляет разработчика от необходимости писать сложную логику определения платформы. Для экспериментов попробуйте: 1. Добавить свои текстуры в разных форматах сжатия, используя инструменты вроде PVRTexTool или ASTC Encoder. 2. Создать несколько текстур с разными ключами и проверить, как они загружаются параллельно. 3. В методе create вывести не только алгоритм сжатия, но и другие свойства объекта logo.frame.source, например, размеры файла. 4. Протестировать производительность на мобильных устройствах, сравнивая загрузку сжатых и несжатых текстур.