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

Первое впечатление от игры формируется в первые секунды. Долгая загрузка с "пустым" экраном может отпугнуть игрока еще до старта. Сцена Preloader в Phaser решает эту проблему, превращая процесс загрузки в управляемый и плавный этап. В этой статье мы разберем, как правильно организовать предзагрузку ассетов (изображений, атласов, аудио), установить базовый URL для удобства разработки и бесшовно перейти к основному игровому миру.

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

Живой запуск

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

Исходный код


class Preloader extends Phaser.Scene
{
    constructor ()
    {
        super({ key: 'preloader' });
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('bg', 'assets/tests/space/nebula.jpg');
        this.load.image('ship', 'assets/tests/space/ship.png');
        this.load.atlas('space', 'assets/tests/space/space.png', 'assets/tests/space/space.json');
    }

    create ()
    {
        this.scene.start('world');
    }
}

Зачем нужна отдельная сцена Preloader?

Ключевая задача Preloader Scene — загрузить все необходимые для старта игры ресурсы (ассеты) до того, как игрок начнет взаимодействие. Если попытаться загружать тяжелые изображения или звуки прямо в основной игровой сцене, игра может "зависнуть" или показывать недогруженные текстуры.

Phaser предлагает встроенный жизненный цикл сцен, и метод preload() идеально подходит для этой задачи. Вся загрузка происходит асинхронно, но внутри этой сцены вы можете контролировать процесс. После завершения загрузки сцена автоматически вызывает метод create(), где вы запускаете следующую сцену.

Настройка пути и загрузка изображений

Первым делом в методе preload() удобно задать базовый URL для всех загружаемых ресурсов. Это избавляет от необходимости прописывать полный путь к каждому файлу.

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

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

this.load.image('bg', 'assets/tests/space/nebula.jpg');
this.load.image('ship', 'assets/tests/space/ship.png');

Здесь 'bg' и 'ship' — это ключи. Phaser загрузит файлы nebula.jpg и ship.png и сохранит их в своем кэше под этими именами.

Работа с атласами спрайтов

Для анимации и оптимизации часто используют атласы спрайтов — один большой PNG-файл, содержащий множество мелких изображений, и JSON-файл с координатами каждого спрайта внутри этого PNG.

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

this.load.atlas('space', 'assets/tests/space/space.png', 'assets/tests/space/space.json');

Метод load.atlas() принимает три аргумента: ключ атласа, путь к изображению и путь к JSON-файлу с данными. После загрузки вы сможете создавать спрайты или анимации, обращаясь к конкретным кадрам по их имени, указанному в JSON, через ключ 'space'.

Завершение загрузки и переход между сценами

Когда все ресурсы, объявленные в методе preload(), загружены, Phaser автоматически вызывает метод create() этой же сцены. Это ваш сигнал к действию.

В create() чаще всего происходит запуск следующей, основной сцены игры.

this.scene.start('world');

Метод this.scene.start() останавливает текущую сцену (Preloader) и запускает сцену с ключом 'world'. Важно, чтобы такая сцена была зарегистрирована в вашей конфигурации игры. Все загруженные в Preloader ассеты будут доступны в новой сцене мгновенно.

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

Preloader Scene — это простой и мощный паттерн, который делает запуск вашей игры на Phaser профессиональным. Он отделяет этап загрузки от игрового процесса, обеспечивая стабильность. Для экспериментов попробуйте добавить в preload() загрузку звуков (this.load.audio()), добавить прогресс-бар, используя события 'progress' из this.load, или загружать данные JSON для уровней. Это основа, которая масштабируется под любые проекты.