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

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

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

    create ()
    {
        const image = this.add.tileSprite(200, 100, 512, 256, 'mushroom');

        image.setInteractive();

        image.setAngle(20);

        image.setOrigin(0);

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

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

            //  So something happens for canvas
            this.x += 2;

        });
    }
}

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

const game = new Phaser.Game(config);

Создание и базовая настройка TileSprite

Основной объект в примере — это TileSprite. В отличие от обычного Sprite, он может замостить (затилировать) свою текстуру по всей своей площади, если его размеры превышают размеры исходного изображения. В нашем случае используется изображение гриба размером 512x256 пикселей.

const image = this.add.tileSprite(200, 100, 512, 256, 'mushroom');

Здесь мы создаем TileSprite с координатами (200, 100), задаем ему ширину и высоту равные размеру изображения (512 и 256), поэтому замощения не происходит. Последний аргумент — ключ загруженного изображения 'mushroom'.

Сразу после создания выполняются три важных метода настройки.

image.setInteractive();
image.setAngle(20);
image.setOrigin(0);

setInteractive() — это ключевой вызов. Он наделяет спрайт способностью обрабатывать события ввода (клики, наведение). Без этого метод on('pointerdown') не сработает. setAngle(20) — поворачивает спрайт на 20 градусов. Это меняет его визуальное представление и влияет на область клика, которая также поворачивается вместе с объектом. setOrigin(0) — устанавливает точку трансформации (origin) объекта в его левый верхний угол (координаты 0,0). По умолчанию она находится в центре. Это важно, так как после поворота на 20 градусов спрайт будет вращаться вокруг своего верхнего левого угла, а не центра.

Обработка клика и изменение внешнего вида

Интерактивность реализуется через подписку на событие 'pointerdown' (нажатие кнопки мыши или касание).

image.on('pointerdown', function ()
{
    this.setTint(Math.random() * 16000000);
    this.x += 2;
});

Внутри функции-обработчика используется this, который ссылается на сам объект image (благодаря использованию обычной функции, а не стрелочной).

this.setTint(Math.random() * 16000000) — этот метод применяет цветовой оттенок (тинт) к спрайту. Аргумент Math.random() * 16000000 генерирует случайное целое число в диапазоне, достаточном для представления различных цветов в формате RGB (шестнадцатеричном). Каждый клик будет окрашивать гриб в случайный цвет.

this.x += 2 — сдвигает спрайт на 2 пикселя вправо по оси X при каждом клике. В комментарии указано, что это сделано "чтобы что-то происходило и для Canvas". Это небольшое визуальное изменение, которое гарантирует перерисовку объекта в контексте рендерера Canvas, даже если изменение тинта по каким-то причинам не сразу отобразится.

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

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

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

const game = new Phaser.Game(config);

type: Phaser.AUTO позволяет Phaser самому выбрать рендерер (WebGL или Canvas). width и height задают размер игрового холста. parent — это ID HTML-элемента, в который будет встроен холст. scene: Example указывает, что стартовой сценой будет наш класс Example. При создании экземпляра игры (new Phaser.Game(config)) автоматически вызываются методы жизненного цикла сцены: preload() для загрузки ассетов и create() для инициализации объектов.

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

Всего несколькими строками кода мы создали интерактивный, вращающийся TileSprite, который реагирует на клики изменением цвета и позиции. Этот паттерн — основа для создания кнопок, интерактивных элементов интерфейса или объектов игрового мира. Для экспериментов попробуйте изменить setOrigin на значения (0.5, 0.5) или (1, 1) и понаблюдайте, как изменится точка вращения. Замените setTint на clearTint, чтобы сбрасывать цвет, или используйте setTilePosition внутри обработчика для анимированного скроллинга текстуры внутри спрайта.