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

Создание интерактивных игровых элементов — основа игрового процесса. Умение обрабатывать действия игрока, такие как клики и касания, позволяет оживить спрайты и интерфейс. Этот пример демонстрирует базовый, но мощный механизм, который можно использовать для кнопок, перетаскивания объектов или запуска игровых событий. Мы разберем, как подписаться на события `pointerdown` и `pointerup` у игрового объекта, чтобы менять его оттенок и обновлять текстовую подсказку. Этот паттерн лежит в основе большинства интерактивных элементов в 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.load.image('pic', 'assets/pics/nayuki.png');
    }

    create ()
    {
        const sprite = this.add.sprite(400, 300, 'pic').setInteractive();

        const text = this.add.text(10, 10, 'Tap the Sprite', { font: '16px Courier', fill: '#00ff00' });

        const text2 = this.add.text(10, 100, `${Phaser.VERSION} + v2`, { font: '16px Courier', fill: '#ffffff' });

        sprite.on('pointerdown', function ()
        {

            this.setTint(Math.random() * 16000000);

            text.setText('DOWN');

        });

        sprite.on('pointerup', () =>
        {

            text.setText('UP');

        });
    }
}

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

const game = new Phaser.Game(config);

Подготовка сцены и загрузка ассетов

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

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

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

create ()
{
    const sprite = this.add.sprite(400, 300, 'pic').setInteractive();
    const text = this.add.text(10, 10, 'Tap the Sprite', { font: '16px Courier', fill: '#00ff00' });
    const text2 = this.add.text(10, 100, `${Phaser.VERSION} + v2`, { font: '16px Courier', fill: '#ffffff' });
    // ... Обработчики событий будут здесь
}

Подписка на событие нажатия (pointerdown)

Чтобы реагировать на начало взаимодействия (когда игрок нажимает кнопку мыши или касается экрана), используется событие pointerdown. Мы подписываемся на него с помощью метода on. Внутри обработчика this ссылается на сам спрайт (sprite), так как используется обычная функция function.

Обработчик выполняет две операции: 1. Изменяет цветовой тон (tint) спрайта на случайный, используя setTint. 2. Обновляет текст первого текстового поля на 'DOWN' с помощью setText.

sprite.on('pointerdown', function ()
{
    this.setTint(Math.random() * 16000000);
    text.setText('DOWN');
});

Вычисление Math.random() * 16000000 дает случайное целое число, которое Phaser интерпретирует как шестнадцатеричный цвет для тонирования. Это быстрый способ добавить визуальный отклик.

Подписка на событие отпускания (pointerup)

Событие pointerup происходит, когда игрок отпускает кнопку мыши или убирает палец с экрана. Это идеальный момент для завершения действия. В этом примере обработчик просто меняет текст обратно на 'UP'.

Обратите внимание на использование стрелочной функции () =>. В данном контексте это не имеет решающего значения, но это хорошая практика, если вам нужно сохранить контекст this родительского метода create (например, для доступа к this.add). Внутри стрелочной функции this будет таким же, как и снаружи.

sprite.on('pointerup', () =>
{
    text.setText('UP');
});

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

Конфигурация и запуск игры

Код завершается стандартной конфигурацией игры и её инстанцированием. Конфиг определяет тип рендерера, элемент-контейнер на странице, размеры холста и основную сцену.

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

const game = new Phaser.Game(config);

Ключевой параметр здесь — scene: Example. Он указывает Phaser, какой класс сцены использовать при запуске игры. После создания экземпляра Phaser.Game автоматически вызываются жизненные циклы сцены: init, preload, create, а затем update.

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

Обработка событий ввода через on('pointerdown') и on('pointerup') — это фундаментальный навык для создания интерактива в Phaser. Вы можете использовать этот паттерн для любых интерактивных объектов. **Идеи для экспериментов:** 1. Добавьте событие pointerover для подсветки спрайта при наведении курсора. 2. Сделайте так, чтобы при нажатии спрайт не только менял тон, но и немного уменьшался (setScale), создавая эффект «вдавливания». 3. Используйте объект pointer, который передается в функцию-обработчик, чтобы получить координаты клика и переместить спрайт в это место. 4. Превратите спрайт в перетаскиваемый объект, активировав в create this.input.setDraggable(sprite) и обрабатывая события dragstart и dragend.