О чем этот пример
Оптимизация графики — ключ к производительности игр. Использование сжатых текстурных атласов позволяет значительно уменьшить объём памяти и ускорить загрузку контента, особенно на мобильных устройствах и в веб-приложениях. В этой статье мы разберём, как загружать и использовать текстуры, сжатые различными алгоритмами (ASTC, ETC, PVRTC, S3TC), с помощью метода `load.texture` в Phaser 3. Вы научитесь создавать гибкую систему загрузки, которая автоматически выбирает оптимальный формат для устройства игрока.
Версия 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/');
const path = 'assets/compressed';
this.load.texture(
{
"key": "labs",
"url": {
'ASTC': { type: 'PVR', textureURL: `${path}/compressed/textures-ASTC-4x4-lRGB.pvr`, atlasURL: `${path}/uncompressed/textures.json` },
'ETC': { type: 'PVR', textureURL: `${path}/compressed/textures-ETC2-lRGB.pvr`, atlasURL: `${path}/uncompressed/textures.json` },
'PVRTC': { type: 'PVR', textureURL: `${path}/compressed/textures-PVRTC-4BPP-lRGB.pvr`, atlasURL: `${path}/uncompressed/textures.json` },
'S3TC': { type: 'PVR', textureURL: `${path}/compressed/textures-S3TC-BC3-lRGB.pvr`, atlasURL: `${path}/uncompressed/textures.json` },
'IMG': { textureURL: `${path}/textures.png`, atlasURL: `${path}/uncompressed/textures.json` }
}
}
);
}
create ()
{
const bubble = this.add.sprite(0, 40, 'labs', 'bubble256').setOrigin(0);
const logo = this.add.sprite(80, 100, 'labs', 'logo').setOrigin(0);
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 и загрузка текстур
Первым шагом является настройка базового пути для всех ресурсов и загрузка самой текстуры с помощью метода load.texture. Этот метод принимает объект конфигурации, который описывает различные форматы сжатия и путь к несжатому атласу.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
const path = 'assets/compressed';
this.load.texture(
{
"key": "labs",
"url": {
'ASTC': { type: 'PVR', textureURL: `${path}/compressed/textures-ASTC-4x4-lRGB.pvr`, atlasURL: `${path}/uncompressed/textures.json` },
'ETC': { type: 'PVR', textureURL: `${path}/compressed/textures-ETC2-lRGB.pvr`, atlasURL: `${path}/uncompressed/textures.json` },
'PVRTC': { type: 'PVR', textureURL: `${path}/compressed/textures-PVRTC-4BPP-lRGB.pvr`, atlasURL: `${path}/uncompressed/textures.json` },
'S3TC': { type: 'PVR', textureURL: `${path}/compressed/textures-S3TC-BC3-lRGB.pvr`, atlasURL: `${path}/uncompressed/textures.json` },
'IMG': { textureURL: `${path}/textures.png`, atlasURL: `${path}/uncompressed/textures.json` }
}
}
);
Здесь key — это уникальный идентификатор, под которым текстура будет доступна в коде (например, 'labs'). Объект url содержит ключи для разных алгоритмов сжатия. Phaser автоматически проверит, какой из форматов поддерживается браузером или устройством, и загрузит подходящий. Формат IMG служит резервным вариантом — обычным PNG-изображением. Важно, что для всех вариантов используется один и тот же файл атласа (textures.json), который описывает расположение отдельных кадров (спрайтов) на текстуре.
Создание спрайтов и доступ к свойствам текстуры
После загрузки текстуры в методе create мы можем создавать спрайты, используя загруженный атлас. Каждый спрайт создаётся с указанием ключа текстуры и имени кадра из атласа.
const bubble = this.add.sprite(0, 40, 'labs', 'bubble256').setOrigin(0);
const logo = this.add.sprite(80, 100, 'labs', 'logo').setOrigin(0);
Метод this.add.sprite принимает координаты X, Y, ключ текстуры и имя кадра. setOrigin(0) устанавливает точку отсчёта (origin) спрайта в его левый верхний угол, что удобно для позиционирования. Ключ 'labs' ссылается на загруженную текстуру, а 'bubble256' и 'logo' — это имена кадров, определённые в JSON-атласе.
После создания спрайта мы можем получить информацию о загруженном формате сжатия через свойство frame.source.compressionAlgorithm.
this.add.text(400, 570, logo.frame.source.compressionAlgorithm).setOrigin(0.5, 0);
Здесь создаётся текстовый объект, который отображает строку с названием алгоритма сжатия (например, 'ASTC'), использованного для текстуры этого спрайта. setOrigin(0.5, 0) центрирует текст по горизонтали относительно точки (400, 570). Это полезно для отладки и демонстрации того, какой формат был выбран движком.
Конфигурация игры и запуск сцены
Для запуска примера необходимо создать стандартную конфигурацию игры Phaser и передать в неё нашу сцену Demo.
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
backgroundColor: '#2d2d6d',
scene: Demo
};
const game = new Phaser.Game(config);
Конфигурация задаёт базовые параметры: type определяет рендерер (WebGL или Canvas), parent — ID HTML-элемента для встраивания канваса, width и height — размеры игрового поля. backgroundColor устанавливает фоновый цвет. Ключевой параметр scene указывает класс сцены, которая будет запущена первой. Создание экземпляра Phaser.Game с этой конфигурацией инициирует весь процесс загрузки и отрисовки.
Как работает выбор формата сжатия
Phaser 3 внутренне проверяет поддержку различных форматов сжатия текстур браузером и графическим API (WebGL). При вызове load.texture с конфигурацией, содержащей несколько форматов, движок проходит по списку в порядке, определённом в объекте (ASTC, ETC, PVRTC, S3TC, IMG), и загружает первый поддерживаемый.
Это поведение критически важно для кроссплатформенной разработки. Например, ASTC эффективен на современных мобильных устройствах с Android, PVRTC — на iOS, а S3TC (BC3) широко поддерживается десктопными браузерами. Формат IMG (обычное PNG) выступает универсальным фолбэком для сред, где аппаратное сжатие текстур недоступно.
Такой подход позволяет разработчику подготовить один набор ассетов в нескольких форматах и не беспокоиться о ручной проверке возможностей устройства — Phaser сделает это автоматически, обеспечив наилучшую производительность.
Что попробовать дальше
Использование метода load.texture для загрузки сжатых текстур — мощный инструмент оптимизации в Phaser 3. Он позволяет автоматически адаптировать графику под возможности устройства, экономя трафик и видеопамять. Для экспериментов попробуйте
- Добавить свои текстуры, сжатые разными алгоритмами, и проверить их отображение на различных устройствах
- Реализовать кастомную логику выбора формата на основе пользовательских данных
- Использовать этот подход для загрузки анимаций, где каждый кадр — часть одного атласа
