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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    constructor()
    {
        super();
    }

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

    create ()
    {
        const goblin = this.add.image(200, 300, 'goblin').setInteractive({ draggable: true });
        const spider = this.add.image(600, 300, 'spider').setInteractive({ draggable: true });

        goblin.on('drag', (pointer, dragX, dragY) => {

            goblin.setPosition(dragX, dragY);
            this.children.bringToTop(goblin);

        });

        spider.on('drag', (pointer, dragX, dragY) => {

            spider.setPosition(dragX, dragY);
            this.children.bringToTop(spider);

        });

        goblin.on('pointermove', (pointer) => {

            console.log('goblin move');

        });

        spider.on('pointermove', (pointer) => {

            console.log('spider move');

        });
    }
}

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

const game = new Phaser.Game(config);

Настройка сцены и загрузка ассетов

В Phaser жизненный цикл сцены управляется методами preload, create и update. В preload мы загружаем изображения, устанавливая базовый URL для удобства.

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

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

В методе create мы создаем два спрайта — гоблина и паука. Метод this.add.image() добавляет изображение с заданными координатами и текстурой. Ключевой момент — вызов .setInteractive({ draggable: true }), который делает объект интерактивным и разрешает его перетаскивание.

const goblin = this.add.image(200, 300, 'goblin').setInteractive({ draggable: true });
const spider = this.add.image(600, 300, 'spider').setInteractive({ draggable: true });

Обработка события drag

Событие drag срабатывает при перемещении зажатого курсора. В обработчике мы получаем новые координаты (dragX, dragY) и обновляем позицию объекта через setPosition. Важно: вызов this.children.bringToTop() перемещает перетаскиваемый объект на верхний слой, чтобы он всегда был поверх других элементов.

goblin.on('drag', (pointer, dragX, dragY) => {
    goblin.setPosition(dragX, dragY);
    this.children.bringToTop(goblin);
});

Отслеживание наведения курсора с pointermove

Событие pointermove реагирует на любое движение курсора над объектом, даже без зажатой кнопки. В примере оно используется для логирования в консоль. Это полезно для подсветки объектов, показа подсказок или изменения курсора.

goblin.on('pointermove', (pointer) => {
    console.log('goblin move');
});

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

Объект config определяет основные параметры игры: тип рендерера, размеры холста, родительский контейнер и главную сцену. Создание экземпляра Phaser.Game с этой конфигурацией инициализирует игровой цикл.

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

const game = new Phaser.Game(config);

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

Вы освоили базовые события взаимодействия в Phaser: drag для перетаскивания и pointermove для реакции на курсор. Для экспериментов попробуйте: добавить физические тела через this.physics.add.image и использовать силу для броска, ограничить область перетаскивания, реализовать "привязку" объектов друг к другу или создать систему инвентаря на основе drag-and-drop.