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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    iter = 1;
    ts;

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.atlas('atlas', 'assets/atlas/megaset-2.png', 'assets/atlas/megaset-2.json');
    }

    create ()
    {
        const atlasTexture = this.textures.get('atlas');

        const frames = atlasTexture.getFrameNames();

        const i = 0;
        let size = 64;

        this.ts = this.add.tileSprite(400, 300, size, size, 'atlas', 'hotdog');

        this.add.text(10, 10, 'Click to change frame and size', { font: '16px Courier', fill: '#ffffff' });

        this.input.on('pointerdown', () =>
        {

            size += 16;

            this.ts.setSize(size, size);

            let frame = Phaser.Utils.Array.GetRandom(frames);

            //  Otherwise you can't see it scrolling
            if (frame === 'platform')
            {
                frame = 'hotdog';
            }

            this.ts.setFrame(frame);

        }, this);
    }

    update ()
    {
        this.ts.tilePositionX += this.iter;
        this.ts.tilePositionY += this.iter * 2;
    }
}

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

const game = new Phaser.Game(config);

Создание базового TileSprite

В методе create() сцены мы инициализируем наш основной объект — TileSprite. Ключевые параметры — это позиция (x, y), начальный размер (width, height), ключ текстуры и имя кадра.

this.ts = this.add.tileSprite(400, 300, size, size, 'atlas', 'hotdog');

Здесь создается TileSprite с центром в точке (400, 300), начальным размером 64x64 пикселя. В качестве текстуры используется атлас 'atlas', а для отображения — конкретный кадр 'hotdog'. Важно: TileSprite автоматически начинает тилировать (повторять) выбранный кадр по своей области.

Обработка клика и изменение размера

Чтобы объект реагировал на ввод пользователя, мы навешиваем обработчик события pointerdown на всю сцену. По каждому клику мы увеличиваем переменную size и применяем новый размер к TileSprite.

size += 16;
this.ts.setSize(size, size);

Метод setSize(width, height) мгновенно изменяет габариты спрайта. В нашем примере с каждым кликом спрайт будет увеличиваться на 16 пикселей по ширине и высоте. Это можно использовать для визуализации роста или надувания объекта.

Динамическая смена текстуры (кадра)

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

let frame = Phaser.Utils.Array.GetRandom(frames);
if (frame === 'platform') {
    frame = 'hotdog';
}
this.ts.setFrame(frame);

Метод setFrame(frameName) меняет базовый кадр, который будет затилирован по всей области спрайта. Проверка на кадр 'platform' нужна, потому что он в данном примере слишком большой и однородный, и на нем не будет видно эффекта прокрутки. После выбора подходящего кадра мы применяем его к TileSprite.

Анимация через постоянную прокрутку

«Магия» движения TileSprite происходит в методе update(), который вызывается каждый кадр игры. Мы меняем свойства смещения тайлов.

this.ts.tilePositionX += this.iter;
this.ts.tilePositionY += this.iter * 2;

Свойства tilePositionX и tilePositionY определяют смещение текстуры внутри спрайта. Увеличивая их каждое обновление, мы создаем эффект бесконечного скроллинга текстуры. В данном случае текстура движется по горизонтали со скоростью iter (1 пиксель/кадр) и в два раза быстрее по вертикали. Это создает простую, но эффективную фоновую анимацию.

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

Используя связку setSize, setFrame и анимацию через tilePosition, вы можете создавать динамичные и отзывчивые игровые объекты на основе TileSprite. Для экспериментов попробуйте: менять размер не на фиксированную величину, а случайно или в зависимости от состояния игры; реализовать плавную анимацию изменения размера с помощью твинов; создать сложный паттерн движения, изменяя tilePosition по синусоидальному закону; или использовать смену кадра для отображения повреждений или уровней мощности объекта.