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

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

Версия 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('apple', 'assets/sprites/apple.png');
    }

    create ()
    {
        const apple = this.add.sprite(100, 100, 'apple');

        apple.setInteractive();

        this.input.setDraggable(apple);

        this.input.on('drag', (pointer, gameObject, dragX, dragY) =>
        {

            gameObject.x = dragX;
            gameObject.y = dragY;

        });
    }
}

const config = {
    type: Phaser.AUTO,
    width: 360,
    height: 640,
    _parent: 'phaser-example',
    backgroundColor: '#efefef',
    scene: Example
};

const game = new Phaser.Game(config);

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

Вся логика примера реализована в классе сцены Example. Первым делом, в методе preload(), мы загружаем изображение, которое будем перетаскивать.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('apple', 'assets/sprites/apple.png');

Метод setBaseURL задает базовый URL для загрузки ресурсов. Затем с помощью load.image мы указываем ключ 'apple' и путь к файлу спрайта. После загрузки к этому спрайту можно обращаться по его ключу.

Создание интерактивного спрайта

В методе create() происходит основная настройка интерактивности. Сначала мы создаем и размещаем спрайт на сцене.

const apple = this.add.sprite(100, 100, 'apple');

Здесь создается спрайт с ключом 'apple' и устанавливается его начальная позиция (x: 100, y: 100).

Чтобы объект мог реагировать на ввод, ему необходимо добавить интерактивность.

apple.setInteractive();

Вызов setInteractive() без аргументов делает весь спрайт зоной для взаимодействия. После этого объект может генерировать события ввода, такие как клик или перетаскивание.

Далее мы сообщаем системе ввода, что этот объект теперь можно перетаскивать.

this.input.setDraggable(apple);

Метод setDraggable добавляет объект apple во внутренний список перетаскиваемых объектов менеджера ввода this.input.

Обработка события перетаскивания

Самое важное — это подписка на событие 'drag', которое генерируется постоянно, пока пользователь удерживает и перемещает объект.

this.input.on('drag', (pointer, gameObject, dragX, dragY) => {
    gameObject.x = dragX;
    gameObject.y = dragY;
});

Обработчик события получает четыре аргумента: - pointer: объект, содержащий информацию о позиции курсора или касания. - gameObject: ссылка на перетаскиваемый игровой объект (в нашем случае — apple). - dragX, dragY: рассчитанные координаты X и Y, куда система ввода предлагает переместить объект.

Внутри обработчика мы просто присваиваем эти координаты свойствам `xиy` нашего спрайта. Это заставляет его визуально следовать за курсором или пальцем пользователя.

Именно так реализуется базовое перетаскивание: система ввода сама вычисляет новые координаты, а разработчику остается только обновить позицию объекта.

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

Для запуска примера необходимо создать конфигурационный объект и инстанс игры Phaser.

const config = {
    type: Phaser.AUTO,
    width: 360,
    height: 640,
    _parent: 'phaser-example',
    backgroundColor: '#efefef',
    scene: Example
};

const game = new Phaser.Game(config);

В конфигурации мы указываем: - type: Phaser.AUTO позволяет движку самому выбрать рендерер (WebGL или Canvas). - width и height: размеры игрового поля. - _parent: ID HTML-элемента, в который будет встроен canvas (опционально). - backgroundColor: цвет фона сцены. - scene: класс нашей сцены Example.

Создание экземпляра new Phaser.Game(config) инициализирует движок и запускает игру.

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

Как видите, для реализации перетаскивания объекта в Phaser требуется всего несколько шагов: сделать объект интерактивным, добавить его в список перетаскиваемых и подписаться на событие drag. Это мощный и простой в использовании механизм. **Идеи для экспериментов:** 1. Попробуйте ограничить область перетаскивания, проверяя координаты dragX и dragY внутри обработчика. 2. Добавьте логику при отпускании объекта (событие 'dragend'), например, чтобы он "прилипал" к определенным зонам. 3. Сделайте перетаскиваемыми несколько разных спрайтов и управляйте их z-index (глубиной), чтобы они перекрывались корректно во время drag&drop.