О чем этот пример
Загрузка картинок, звуков и атласов — рутинная, но критически важная часть разработки игры. Phaser предлагает несколько способов вызова методов загрузчика, от классических до объектно-ориентированных. В этой статье мы разберем, как использовать объектный синтаксис метода `load.image()`, который дает больше контроля над процессом, позволяет тонко настраивать XHR-запросы и делает код чище при загрузке нескольких файлов. Это полезно для организации сложных сцен загрузки и работы с защищенными ресурсами.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
// Load via an object
// this.load.image({ key: 'bunny', url: 'assets/sprites/bunny.png' });
// Load via an array of objects
/*
this.load.image([
{ key: 'bunny', url: 'assets/sprites/bunny.png' },
{ key: 'atari', url: 'assets/sprites/atari400.png' },
{ key: 'logo', url: 'assets/sprites/phaser2.png' }
]);
*/
// Object based including XHR Settings
this.load.image({
key: 'bunny',
url: 'assets/sprites/bunny.png',
xhr: {
user: 'root',
password: 'th3G1bs0n',
timeout: 10,
header: 'Content-Type',
headerValue: 'image/png'
}
});
/*
// Auto-filename based on key:
// Will load bunny.png from the defined path, because '.png' is the default extension.
this.load.image({ key: 'bunny' });
// Will load bunny.jpg from the defined path, because of the 'ext' property.
this.load.image({ key: 'bunny', extension: 'jpg' });
// ----------------------
// Texture Atlas Examples
// ----------------------
// Original atlas loader signature:
// this.load.atlas(key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings)
this.load.atlas('level1', 'assets/level1/items.png', 'assets/level1/items.json');
// Object based
this.load.atlas({ key: 'level1', textureURL: 'assets/level1/items.png', atlasURL: 'assets/level1/items.json' });
*/
}
create ()
{
this.add.image(400, 300, 'bunny');
}
}
const config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Классический vs. объектный синтаксис
Традиционный способ загрузки изображения в Phaser хорошо знаком: передать ключ и URL строковыми аргументами. Однако API загрузчика поддерживает и альтернативный, объектный синтаксис.
Классический вызов выглядит так:
this.load.image('bunny', 'assets/sprites/bunny.png');
Его объектный аналог принимает один аргумент — объект конфигурации:
this.load.image({ key: 'bunny', url: 'assets/sprites/bunny.png' });
На первый взгляд, разница невелика. Однако объектный подход раскрывает свой потенциал, когда нужно передать дополнительные параметры, такие как настройки XHR, или загрузить несколько ресурсов одним вызовом через массив объектов.
Загрузка с настройкой XHR-запроса
Главное преимущество объектного синтаксиса — возможность детальной настройки HTTP-запроса через свойство xhr. Это бывает необходимо для доступа к ресурсам, защищенным базовой аутентификацией (Basic Auth), или для установки специфичных заголовков и таймаутов.
В примере из исходника показана загрузка спрайта с передачей учетных данных и заголовка:
this.load.image({
key: 'bunny',
url: 'assets/sprites/bunny.png',
xhr: {
user: 'root',
password: 'th3G1bs0n',
timeout: 10,
header: 'Content-Type',
headerValue: 'image/png'
}
});
Здесь внутри свойства xhr задаются:
- user и password для HTTP-аутентификации.
- timeout для ограничения времени запроса (в данном случае всего 10 мс, что маловероятно для реального использования).
- header и headerValue для установки произвольного HTTP-заголовка (в примере явно указывается MIME-тип).
Без объектного синтаксиса передать эти параметры в load.image() было бы невозможно.
Массовая загрузка и умные умолчания
Объектный синтаксис отлично подходит для загрузки нескольких ресурсов одним махом. Вместо нескольких вызовов можно передать методу массив объектов конфигурации.
Пример из закомментированного кода:
this.load.image([
{ key: 'bunny', url: 'assets/sprites/bunny.png' },
{ key: 'atari', url: 'assets/sprites/atari400.png' },
{ key: 'logo', url: 'assets/sprites/phaser2.png' }
]);
Такой подход делает код в preload() более структурированным, особенно когда ресурсов много.
Еще одна удобная фича — автоматическое формирование имени файла на основе ключа. Если свойство url не указано, загрузчик попробует загрузить файл по пути, состоящему из базового URL, ключа и расширения.
// Загрузит <baseURL>/bunny.png
this.load.image({ key: 'bunny' });
// Загрузит <baseURL>/bunny.jpg, т.к. расширение переопределено
this.load.image({ key: 'bunny', extension: 'jpg' });
Это работает, если вы предварительно установили базовый путь через this.load.setBaseURL(), как сделано в примере. Такой подход стандартизирует именование файлов в проекте.
Применение к другим типам ресурсов
Объектный синтаксис — не эксклюзив для load.image(). Он поддерживается и другими методами загрузчика. Например, для загрузки атласа текстур (atlas) традиционный способ требует нескольких аргументов:
this.load.atlas('level1', 'assets/level1/items.png', 'assets/level1/items.json');
Его можно переписать в объектном стиле, что повышает читаемость, особенно при наличии XHR-настроек:
this.load.atlas({
key: 'level1',
textureURL: 'assets/level1/items.png',
atlasURL: 'assets/level1/items.json'
});
Аналогичный принцип, вероятно, применим к load.audio, load.bitmapFont и другим методам, где важна конфигурация. Всегда проверяйте актуальную документацию Phaser для подтверждения.
Что попробовать дальше
Объектный синтаксис методов загрузчика в Phaser — это мощный инструмент для написания чистого, гибкого и надежного кода. Он незаменим при работе с защищенными ресурсами, массовой загрузке и желании придерживаться консистентного стиля.
**Идеи для экспериментов:**
1. Создайте систему, которая динамически формирует массив объектов для load.image() на основе JSON-манифеста ресурсов уровня.
2. Попробуйте загрузить аудиофайл с кастомным заголовком Authorization через свойство xhr.
3. Реализуйте «умный» загрузчик, который подставляет расширение файла (extension) на основе ключа, если файл с расширением по умолчанию не найден (используя событие LOAD_ERROR).
