Загрузчик Phaser.Loader и его события

В Phaser, одной из ключевых задач при создании игры является корректная загрузка ресурсов — изображений, спрайтов, аудио, шрифтов и других ассетов. Для этого используется объект Phaser.Loader, который предоставляет удобный интерфейс для организации асинхронной загрузки и контроля состояния процесса.

Phaser.Loader работает на основе очереди загрузки. Все ресурсы сначала добавляются в очередь, а затем начинается процесс загрузки с вызовом метода start(). Загрузка выполняется асинхронно, что позволяет отображать прогресс и выполнять другие действия во время загрузки.

const loader = new Phaser.Loader(scene);

loader.image('player', 'assets/player.png');
loader.audio('theme', 'assets/theme.mp3');

loader.start();

В этом примере создается новый загрузчик, добавляются два ресурса — изображение и аудио, и начинается процесс загрузки.

Типы ресурсов и методы их добавления

Phaser поддерживает различные типы ассетов, для каждого предусмотрены специальные методы:

  • Изображения и спрайт-листы:

    • loader.image(key, url) — для одиночных изображений.
    • loader.spritesheet(key, url, { frameWidth, frameHeight }) — для спрайт-листов.
  • Анимации и текстуры:

    • loader.atlas(key, textureURL, atlasDataURL) — для атласов текстур.
  • Аудио:

    • loader.audio(key, urls) — массив форматов (.mp3, .ogg) для кроссбраузерной совместимости.
  • Шрифты и данные:

    • loader.bitmapFont(key, textureURL, xmlURL) — для bitmap-шрифтов.
    • loader.json(key, url) — для JSON-конфигураций, данных уровня и прочего.

Каждый метод возвращает объект загрузки, который можно использовать для привязки событий на конкретный ресурс.

События загрузчика

Phaser.Loader предоставляет богатый набор событий, позволяющих отслеживать процесс и управлять поведением игры в момент загрузки.

Основные события

  1. progress Срабатывает при изменении прогресса загрузки. Передает значение от 0 до 1, которое можно использовать для отображения индикатора загрузки.

    loader.on('progress', (value) => {
        console.log(`Загрузка: ${Math.floor(value * 100)}%`);
    });
  2. fileprogress Триггерится при загрузке каждого отдельного файла. Позволяет узнать, какой ресурс загружается в данный момент.

    loader.on('fileprogress', (file) => {
        console.log(`Загружается: ${file.key}`);
    });
  3. complete Срабатывает после завершения загрузки всех ресурсов. Идеально подходит для запуска сцены или анимации загрузочного экрана.

    loader.on('complete', () => {
        console.log('Все ресурсы загружены');
    });
  4. loaderror Возникает при ошибке загрузки файла. Позволяет обработать сбои и предпринять действия, например, повторить загрузку или вывести сообщение.

    loader.on('loaderror', (file) => {
        console.error(`Ошибка загрузки файла: ${file.key}`);
    });
  5. start и shutdown

    • start — вызывается при запуске процесса загрузки.
    • shutdown — вызывается после завершения загрузки или отмены загрузчика.

Работа с событиями через цепочки

Phaser позволяет комбинировать события и управлять ими через цепочки вызовов, что упрощает код для сложных загрузочных экранов:

loader
    .on('progress', (value) => updateProgressBar(value))
    .on('fileprogress', (file) => showFileName(file.key))
    .on('complete', () => startGame())
    .start();

Асинхронная природа загрузки

Важно понимать, что загрузка в Phaser полностью асинхронна. Это означает, что ресурсы не доступны до тех пор, пока не сработает событие complete. Попытка использовать изображения или аудио до завершения загрузки приведет к ошибкам.

Для оптимизации можно загружать ресурсы партиями, например, сначала базовые ассеты, затем дополнительные текстуры или аудио, чтобы ускорить отображение стартовой сцены.

// Первая партия: интерфейс и основной персонаж
loader.image('player', 'assets/player.png')
      .image('ui', 'assets/ui.png')
      .start();

// После завершения первой партии — вторая партия ассетов
loader.on('complete', () => {
    loader.image('background', 'assets/background.png').start();
});

Кэширование и повторное использование ресурсов

После загрузки ресурсы автоматически сохраняются в кэше сцены, и к ним можно обращаться через ключ:

scene.add.image(400, 300, 'player');
scene.sound.play('theme');

Ключевое преимущество кэша — возможность многократного использования одного ресурса без повторной загрузки, что существенно экономит память и ускоряет работу игры.

Особенности работы с Phaser 3

  • Все загрузчики привязаны к конкретной сцене (scene.load). При смене сцены старый загрузчик становится недоступным.
  • Можно использовать глобальный загрузчик для предварительной загрузки ассетов всех сцен.
  • Phaser автоматически управляет порядком загрузки, но события позволяют вмешиваться и строить кастомные индикаторы, например, с анимацией прогресс-бара.

Рекомендации по организации загрузки

  • Разделять ресурсы на категории: спрайты, интерфейс, аудио, уровни.
  • Загружать только необходимые на старте ассеты, остальные — по мере необходимости.
  • Использовать события fileprogress для отображения текущего файла и progress — для глобального индикатора.
  • Обрабатывать ошибки через loaderror, чтобы игра не зависала при недоступных ресурсах.
  • Использовать кэш для повторного использования ассетов вместо повторной загрузки.

Эффективное управление Phaser.Loader и его событиями позволяет строить плавные загрузочные экраны, оптимизировать время старта игры и контролировать использование ресурсов.