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

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

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

Живой запуск

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

Исходный код


function preload ()
{
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('face', 'assets/pics/bw-face.png');
}

function create ()
{
    this.add.image(400, 300, 'face');
}

const config = {
    type: Phaser.CANVAS,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create
    }
};

const game = new Phaser.Game(config);

Структура конфигурации игры

Каждая игра на Phaser начинается с объекта конфигурации. В нем задаются основные параметры: тип рендерера, размеры холста и, что самое важное, сцена, которая будет запущена первой.

const config = {
    type: Phaser.CANVAS,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create
    }
};

Здесь мы указываем, что используем рендерер CANVAS. Параметры width и height определяют внутреннее разрешение игры. Ключевой элемент — scene. Это объект, методы которого (preload и create) Phaser будет вызывать в определенный момент жизненного цикла. Создание экземпляра игры new Phaser.Game(config) инициирует весь процесс.

Этап предзагрузки: метод preload

Прежде чем использовать изображения или звуки, их нужно загрузить в кеш браузера. Для этого служит метод preload. Внутри него мы получаем доступ к менеджеру загрузки через this.load.

function preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('face', 'assets/pics/bw-face.png');
}

Сначала метод setBaseURL задает базовый URL-адрес для всех последующих загрузок. Это удобно, чтобы не писать полный путь к каждому файлу. Затем this.load.image регистрирует загрузку изображения. Первый аргумент ('face') — это уникальный ключ-идентификатор, по которому мы будем обращаться к изображению позже. Второй аргумент — относительный путь к файлу от базового URL.

Создание игровых объектов: метод create

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

function create ()
{
    this.add.image(400, 300, 'face');
}

Здесь используется фабрика игровых объектов this.add. Метод image создает и возвращает новый объект изображения (Image Game Object). Аргументы 400 и 300 — это координаты X и Y центра изображения на холсте. Третий аргумент 'face' — это тот самый ключ, который мы указали при загрузке в preload. Объект автоматически добавляется на дисплейный список текущей сцены и становится видимым.

Почему именно такой порядок?

Phaser следует строгому жизненному циклу сцены (Scene Lifecycle). Это обеспечивает предсказуемость и отсутствие ошибок, связанных с попыткой отрисовать еще не загруженную текстуру.

1. **PRELOAD**: Выполняется preload. Все вызовы this.load.* ставят ресурсы в очередь на загрузку. 2. **CREATE**: Только после успешной загрузки всех ресурсов из очереди выполняется create. Гарантируется, что ключ 'face' уже существует в текстовом кеше игры. 3. **UPDATE/RENDER**: После create начинается игровой цикл с методами update (логика) и render (отрисовка), которые в нашем примере не используются.

Нарушение этого порядка (например, попытка создать изображение в preload) приведет к ошибке.

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

Вы только что создали первую рабочую сцену на Phaser! Основной принцип — разделение загрузки (preload) и инициализации (create). Для экспериментов попробуйте: загрузить другое изображение с сайта like Picsum, создать несколько картинок с разными координатами или добавить в create простую интерактивность через this.input.on('pointerdown', ...). Это первый шаг к созданию полноценной игры.