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

Интерактивность — ключевой элемент вовлечения игрока. В Phaser 3 события указателя (мыши или касания) позволяют легко реагировать на действия пользователя. В этой статье мы разберем, как использовать событие `pointermove` для создания визуального следа за движением курсора. Этот прием полезен для создания эффектов рисования, интерактивных меню или визуальной обратной связи в играх-головоломках.

Версия 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.spritesheet('balls', 'assets/sprites/balls.png', { frameWidth: 17, frameHeight: 17 });
    }

    create ()
    {
        this.input.on('pointermove', function (pointer)
        {

            this.add.image(pointer.x, pointer.y, 'balls', Phaser.Math.Between(0, 5));

        }, this);
    }
}

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

const game = new Phaser.Game(config);

Что делает событие pointermove?

Событие pointermove генерируется каждый раз, когда указатель (мышь, палец или перо) перемещается над областью рендеринга игры. Оно является частью системы ввода Phaser (this.input). Это позволяет вашей игре реагировать на движение, даже если кнопка не нажата.

Обработчик события получает объект pointer, который содержит актуальные координаты (pointer.x, pointer.y) и другую полезную информацию о состоянии ввода.

Структура примера: от загрузки до создания

Код примера следует стандартной структуре сцены Phaser с методами preload и create.

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

this.load.spritesheet('balls', 'assets/sprites/balls.png', { frameWidth: 17, frameHeight: 17 });

Метод create — это место, где мы настраиваем логику сцены. Именно здесь происходит подписка на событие.

create ()
{
    this.input.on('pointermove', function (pointer)
    {
        // Код обработчика
    }, this);
}

Обратите внимание на третий аргумент this, переданный в метод on. Он задает контекст выполнения для callback-функции, чтобы внутри нее ключевое слово this ссылалось на текущую сцену, а не на объект события. Это критически важно для доступа к методам сцены, таким как this.add.image.

Логика обработчика события

Каждый раз при движении указателя вызывается переданная функция. Ее задача — создать новый спрайт в текущей позиции курсора.

this.add.image(pointer.x, pointer.y, 'balls', Phaser.Math.Between(0, 5));

Разберем аргументы метода this.add.image: 1. pointer.x, pointer.y — координаты для размещения изображения. 2. 'balls' — ключ текстуры, загруженной в preload. 3. Phaser.Math.Between(0, 5) — это индекс кадра из спрайтшита. Утилита Phaser.Math.Between случайным образом выбирает целое число от 0 до 5 включительно. Таким образом, каждый новый шарик будет иметь случайный цвет из шести доступных в спрайтшите.

В результате получается плавный след из разноцветных шариков, который повторяет траекторию движения мыши.

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

Пример завершается стандартной конфигурацией игры и ее инстанцированием.

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

const game = new Phaser.Game(config);

Эта конфигурация создает игровой экран размером 800x600 пикселей, использует автоматический выбор WebGL или Canvas рендерера и указывает наш класс Example в качестве стартовой сцены.

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

Событие pointermove — это мощный инструмент для создания динамичной и отзывчивой интерактивности. Показанный пример демонстрирует его базовое применение. **Идеи для экспериментов:** 1. Измените логику внутри обработчика: например, создавайте спрайты не при каждом движении, а через определенное расстояние, используя проверку pointer.getDistance(), чтобы получить пунктирную линию. 2. Добавьте физические тела создаваемым спрайтам с помощью this.physics.add.image, чтобы шарики падали, сталкивались или отскакивали от границ мира. 3. Используйте другую текстуру или анимированный спрайт для создания более сложных эффектов (след из огня, пыли или магических частиц). 4. Обрабатывайте событие только при нажатой кнопке мыши (pointer.isDown), реализовав режим рисования.