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

При разработке игр важно управлять процессом загрузки ресурсов. Стандартный общий индикатор прогресса не всегда подходит, особенно когда нужно визуализировать загрузку конкретного тяжёлого ресурса, например, аудиофайла. Событие `fileprogress` в Phaser даёт точный контроль, позволяя создавать индивидуальные индикаторы для каждого файла. Это полезно для создания уникального и отзывчивого пользовательского интерфейса загрузки, который точно информирует игрока о состоянии процесса.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.add.image(400, 300, 'bear').setScale(2);

        const progress = this.add.graphics();

        this.load.on('fileprogress', (file, value) =>
        {

            if (file.key === 'goldrunner')
            {
                progress.clear();
                progress.fillStyle(0xffffff, 0.4);
                progress.fillRect(450, 500 - (value * 400), 200, value * 400);
            }

        });

        this.load.on('complete', () =>
        {

            progress.destroy();

        });

        this.load.audio('goldrunner', 'assets/audio/Scyphe-Goldrunner_(Maccie_Pimp_Me Up_Remix).mp3');
    }

    create ()
    {
        const music = this.sound.add('goldrunner');

        music.play();
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    pixelArt: true,
    scene: Example
};

const game = new Phaser.Game(config);

Настройка сцены и загрузки

В методе preload мы выполняем начальную настройку. Сначала задаём базовый URL для загрузчиков с помощью this.load.setBaseURL. Это позволяет указывать относительные пути для ресурсов.

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

Ключевой элемент — создание графического объекта (Graphics), который будет отрисовывать наш кастомный прогресс-бар. Объект progress — это холст для рисования примитивов.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.add.image(400, 300, 'bear').setScale(2);
const progress = this.add.graphics();

Обработка события fileprogress

Событие fileprogress генерируется для каждого файла во время его загрузки. Обработчик этого события получает два параметра: объект file (с информацией о загружаемом ресурсе) и value (число от 0 до 1, отражающее прогресс загрузки именно этого файла).

Внутри обработчика мы проверяем ключ файла (file.key). Это позволяет реагировать на прогресс загрузки только нужного нам ресурса, в данном случае — аудиотрека с ключом 'goldrunner'.

Если ключ совпадает, мы: 1. Очищаем предыдущее состояние полосы с помощью progress.clear(). 2. Задаём стиль заливки (цвет и прозрачность) через progress.fillStyle. 3. Рисуем прямоугольник, высота которого зависит от значения value. Используется формула 500 - (value * 400), чтобы полоса "росла" снизу вверх.

this.load.on('fileprogress', (file, value) => {
    if (file.key === 'goldrunner') {
        progress.clear();
        progress.fillStyle(0xffffff, 0.4);
        progress.fillRect(450, 500 - (value * 400), 200, value * 400);
    }
});

Завершение загрузки и запуск музыки

Когда все файлы загружены, срабатывает событие complete. В его обработчике мы уничтожаем графический объект progress, так как индикатор больше не нужен. Это важный шаг для освобождения ресурсов.

Непосредственно загрузка аудиофайла инициируется вызовом this.load.audio. Обратите внимание: регистрация слушателей событий (on) должна происходить *до* начала загрузки файлов, иначе события не будут перехвачены.

В методе create, который выполняется после завершения preload, мы создаём экземпляр звука через this.sound.add и запускаем его воспроизведение командой play.

this.load.on('complete', () => {
    progress.destroy();
});
this.load.audio('goldrunner', 'assets/audio/Scyphe-Goldrunner_(Maccie_Pimp_Me Up_Remix).mp3');
const music = this.sound.add('goldrunner');
music.play();

Конфигурация игры

Здесь определяется базовая конфигурация игры Phaser. Важные параметры: - type: Рендерер (WebGL или Canvas). - width и height: Размер игрового холста. - parent: ID DOM-элемента, куда будет встроен холст. - scene: Класс главной сцены.

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    pixelArt: true,
    scene: Example
};
const game = new Phaser.Game(config);

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

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