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

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

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

Живой запуск

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

Исходный код


const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create,
        extend: {
            hello: 1,
            test: 'atari',
            addImage: addImage
        }
    }
};

const game = new Phaser.Game(config);

function addImage (x, y)
{
    this.add.image(x, y, 'mech');
}

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

function create ()
{
    //  We are able to use 'this.addImage' because we have defined 'addImage' as a local
    //  method in the scene.extend configuration.

    this.addImage(300, 200);
    this.addImage(600, 500);
    this.addImage(100, 400);

    //  We have also added the properties 'hello' and 'test' as Scene level properties,
    //  defined in the scene.extend configuration, meaning we can access them like this:

    console.log(this.hello);
    console.log(this.test);
}

Что такое `extend` и зачем он нужен

При создании сцены в Phaser вы можете определить её через объект конфигурации, указав стандартные методы жизненного цикла: preload, create, update. Однако иногда в этих методах требуется выполнять однотипные операции, например, добавлять спрайты с повторяющимися настройками. Вместо того чтобы копировать код, можно расширить сцену своими методами и свойствами с помощью опции extend.

Объект extend добавляется в конфигурацию сцены и содержит ключи, которые будут "примешаны" к экземпляру сцены. Это означает, что все функции из extend становятся методами сцены, доступными через this, а значения — её свойствами. Такой подход помогает избежать загромождения глобальной области видимости и делает код сцены более структурированным.

scene: {
    preload: preload,
    create: create,
    extend: {
        hello: 1,
        test: 'atari',
        addImage: addImage
    }
}

Добавляем пользовательский метод в сцену

В примере мы создаём метод addImage, который упрощает добавление изображения на сцену. Этот метод принимает координаты `xиyи используетthis.add.imageдля отрисовки спрайта с ключом'mech'. Поскольку метод добавлен черезextend, он доступен в любом другом методе сцены черезthis.addImage`.

Обратите внимание: внутри addImage мы используем this.add.image. Ключевое слово this здесь ссылается на экземпляр сцены, потому что Phaser автоматически привязывает контекст. Это позволяет нам обращаться к стандартным API Phaser, таким как this.add, без дополнительных усилий.

function addImage (x, y)
{
    this.add.image(x, y, 'mech');
}

В методе create мы вызываем this.addImage трижды с разными координатами. Каждый вызов рисует одно и то же изображение в указанной позиции. Без extend нам пришлось бы дублировать вызов this.add.image для каждого спрайта или создавать отдельную функцию вне сцены, что менее удобно.

Использование свойств из `extend`

Помимо методов, через extend можно добавить любые данные как свойства сцены. В примере мы определяем два свойства: hello со значением `1иtestсо строкой'atari'. Эти свойства становятся частью экземпляра сцены и доступны в её методах, таких какcreate`.

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

console.log(this.hello); // Выведет: 1
console.log(this.test);  // Выведет: 'atari'

В методе create мы выводим значения этих свойств в консоль. Поскольку они добавлены через extend, обращение к ним происходит напрямую через this, как и к стандартным свойствам Phaser.

Загрузка ресурсов и инициализация

Прежде чем использовать метод addImage, необходимо загрузить изображение. Это делается в стандартном методе preload, где мы указываем базовый URL и загружаем изображение с ключом 'mech'. Обратите внимание: this.load доступен в preload благодаря контексту сцены.

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

После загрузки в create мы можем безопасно вызывать this.addImage, так как ресурс уже готов. Phaser автоматически управляет порядком выполнения: сначала preload, затем create. Это гарантирует, что все изображения будут доступны при отрисовке.

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

Использование extend в конфигурации сцены — это простой и эффективный способ расширить её функциональность без создания сложных классов. Вы можете добавлять вспомогательные методы, хранить данные и делать код более чистым. Попробуйте экспериментировать с этим подходом: например, добавьте метод для создания анимированных спрайтов или свойство для управления сложностью игры. Также можно комбинировать extend с другими возможностями Phaser, такими как системы событий или физика, чтобы создавать более динамичные сцены.