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

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

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

Живой запуск

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

Исходный код


class DemoC extends Phaser.Scene
{
    constructor ()
    {
        super({ key: 'DemoC', active: true });
        this.tilesprites = [];
    }

    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 frames = ['atari400', 'bunny', 'cokecan', 'copy-that-floppy', 'hotdog'];

        for (let i = 0; i < frames.length; ++i)
        {
            this.tilesprites[i] = this.add.tileSprite(i * 160, 0, 160, 600, 'atlas', frames[i]);
            this.tilesprites[i].setOrigin(0)
            // this.tilesprites[i].setTint(0xff00ff, 0xffff00, 0x0000ff, 0xff0000);
        }

        let cam = this.cameras.main;

        cam.x = 0;
        cam.y = 600;
    }

    update ()
    {
        let x = 4;

        for (let i = 0; i < this.tilesprites.length; ++i)
        {
            this.tilesprites[i].tilePositionX += x;
            this.tilesprites[i].tilePositionY += x;
            x *= -1;
        }
    }
}

Инициализация и загрузка ресурсов

Класс сцены DemoC наследуется от Phaser.Scene. В конструкторе мы устанавливаем ключ сцены и флаг active: true, что позволяет сцене обновляться сразу после создания. Также инициализируется массив tilesprites для хранения наших объектов.

В методе preload задается базовый URL для загрузки и загружается атлас текстур. Атлас — это один большой изображение со множеством отдельных спрайтов (фреймов), что оптимизирует загрузку и отрисовку.

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');

Создание массива TileSprite

В методе create определяется массив имен фреймов frames, которые будут использоваться из загруженного атласа.

Далее в цикле создаются объекты TileSprite. Ключевой метод — this.add.tileSprite(x, y, width, height, textureKey, frameKey). Он создает спрайт, текстура которого будет мозаично повторяться (плиткой) внутри заданной прямоугольной области.

this.tilesprites[i] = this.add.tileSprite(i * 160, 0, 160, 600, 'atlas', frames[i]);
this.tilesprites[i].setOrigin(0);

Параметры: * i * 160, 0 — координаты левого верхнего угла спрайта. Спрайты выстраиваются в ряд по горизонтали с шагом 160 пикселей. * 160, 600 — ширина и высота области отрисовки плиточного спрайта. * 'atlas' — ключ загруженной текстуры. * frames[i] — ключ конкретного фрейма внутри атласа. * setOrigin(0) устанавливает точку привязки (origin) спрайта в его левый верхний угол. Это упрощает позиционирование в данном примере.

После создания спрайтов происходит смещение основной камеры this.cameras.main вниз, чтобы она смотрела на созданный ряд спрайтов.

Анимация через управление tilePosition

Вся магия движения происходит в методе update, который вызывается на каждом кадре.

Для анимации TileSprite используются свойства tilePositionX и tilePositionY. Они определяют смещение внутренней текстуры относительно своего контейнера. Изменяя эти значения, мы создаем иллюзию бесконечного движения или прокрутки текстуры.

this.tilesprites[i].tilePositionX += x;
this.tilesprites[i].tilePositionY += x;
x *= -1;

В примере используется переменная `x, начальное значение которой равно 4. На каждом шаге цикла для текущего спрайта увеличиваются иtilePositionX, иtilePositionYна это значение, а затемx` меняет знак на противоположный. Это приводит к тому, что соседние спрайты движутся в противоположных направлениях (один вправо и вниз, следующий — влево и вверх), создавая интересный волнообразный эффект.

Практическое применение и вариации

Основное применение TileSprite — создание бесшовных фонов (гор, облаков, воды), которые плавно перемещаются относительно игрока. Это классический способ реализации параллакса.

Вот как можно изменить пример для создания слоистого параллакса:

// В create
this.farBg = this.add.tileSprite(0, 0, width, height, 'bg_far').setOrigin(0);
this.nearBg = this.add.tileSprite(0, 0, width, height, 'bg_near').setOrigin(0);

// В update
this.farBg.tilePositionX += 0.5; // Дальний слой движется медленнее
this.nearBg.tilePositionX += 2;   // Ближний слой движется быстрее

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

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

Класс TileSprite предоставляет простой и производительный способ работы с повторяющимися текстурами. Освоив управление tilePosition, вы сможете оживлять игровые фоны, создавать сложные параллакс-эффекты и оптимизировать рендеринг. Для экспериментов попробуйте: изменить скорость и направление движения каждого спрайта независимо; использовать tileScale для анимированного масштабирования текстуры; привязать движение tilePosition к скорости игрового персонажа для создания динамичного фона.