О чем этот пример
Механика перетаскивания объектов — одна из базовых и часто используемых в играх и интерактивных приложениях. Будь то пазлы, головоломки, редакторы уровней или стратегии, возможность перемещать элементы мышью или касанием пальца значительно улучшает пользовательский опыт. В Phaser 3 реализовать это проще, чем кажется, благодаря встроенной системе Input. Эта статья покажет, как за несколько строк кода добавить плавное и отзывчивое перетаскивание любому спрайту или игровому объекту.
Версия 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('bg', 'assets/skies/gradient29.png');
this.load.image('char', 'assets/pics/nayuki.png');
}
create ()
{
this.add.image(400, 300, 'bg');
this.add.text(16, 16, 'Drag the Sprite').setFontSize(24).setShadow(1, 1);
const sprite = this.add.sprite(400, 300, 'char');
sprite.setInteractive({ draggable: true });
sprite.on('drag', (pointer, dragX, dragY) => sprite.setPosition(dragX, dragY));
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и загрузка ресурсов
Работа начинается с создания класса сцены, унаследованного от Phaser.Scene. В методе preload мы загружаем необходимые изображения. В данном примере это фон (bg) и изображение персонажа (char).
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bg', 'assets/skies/gradient29.png');
this.load.image('char', 'assets/pics/nayuki.png');
}
Создание объектов и настройка интерактивности
В методе create мы размещаем фон и текстовую подсказку. Ключевой шаг — создание спрайта и вызов метода setInteractive с опцией { draggable: true }. Это сообщает Phaser, что данный объект должен реагировать на события ввода и его можно перетаскивать.
create ()
{
this.add.image(400, 300, 'bg');
this.add.text(16, 16, 'Drag the Sprite').setFontSize(24).setShadow(1, 1);
const sprite = this.add.sprite(400, 300, 'char');
sprite.setInteractive({ draggable: true });
}
Обработка события перетаскивания
Чтобы объект действительно начал двигаться за указателем, необходимо подписаться на событие 'drag'. Это событие генерируется непрерывно во время процесса перетаскивания. В обработчик передаются координаты указателя (dragX, dragY), которые мы используем для обновления позиции спрайта с помощью setPosition.
sprite.on('drag', (pointer, dragX, dragY) => sprite.setPosition(dragX, dragY));
Таким образом, в каждом кадре во время перетаскивания позиция спрайта синхронизируется с позицией курсора мыши или касания.
Конфигурация и запуск игры
Как и в любом проекте Phaser 3, необходимо создать объект конфигурации, указав тип рендерера, размеры холста и класс основной сцены. После этого создается экземпляр игры Phaser.Game.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Всего три шага: setInteractive({ draggable: true }), подписка на событие 'drag' и обновление позиции — и механика перетаскивания готова. Это основа, которую можно развивать. Попробуйте ограничить область перетаскивания, добавить физическое тело объекту для столкновений или реализовать "привязку" к сетке при отпускании. Также можно использовать события 'dragstart' и 'dragend' для визуальной обратной связи, например, изменения масштаба или прозрачности спрайта.
