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

При разработке игр часто возникает задача заполнения больших областей фона или элементов интерфейса повторяющимся рисунком без видимых швов. Рисовать каждый спрайт вручную неэффективно. Встроенный объект RenderTexture в Phaser и его метод `repeat` решают эту проблему, позволяя программно генерировать тайловые текстуры прямо во время выполнения игры. Эта техника экономит ресурсы и упрощает создание динамических фонов.

Версия 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('beer', 'assets/sprites/beer.png');
        this.load.image('crate', 'assets/sprites/crate.png');
        this.load.image('raster', 'assets/demoscene/large-raster32.png');
    }

    create ()
    {
        const rt1 = this.add.renderTexture(0, 0, 400, 600).setOrigin(0, 0);
        const rt2 = this.add.renderTexture(400, 0, 400, 600).setOrigin(0, 0);

        rt1.repeat('crate', null, 0, 0).render();
        rt2.repeat('raster', null, 0, 0).render();
    }
}

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

const game = new Phaser.Game(config);

Что такое RenderTexture?

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

Основное преимущество — возможность предварительно сгенерировать сложную композицию один раз и отображать её как единое целое, что дешевле для производительности, чем рендерить множество отдельных объектов каждый кадр.

Создать RenderTexture можно через фабрику this.add.renderTexture(x, y, width, height).

Метод repeat: основы работы

Ключевой метод для нашей задачи — repeat. Он заполняет всю область RenderTexture повторяющимся изображением (тайлом) на основе переданного текстового ключа.

Сигнатура метода:

repeat(key, frame, x, y)

- key (string): Ключ изображения, загруженного в preload. - frame (string/integer): Необязательный параметр. Ключ или индекс конкретного кадра из мультиатласа. В нашем примере передаётся null, что означает использование базового изображения. - `x,y` (number): Необязательные координаты смещения начала тайлинга внутри текстуры. По умолчанию — 0.

Важно! Вызов repeat только подготавливает команду для отрисовки. Чтобы результат появился на экране, необходимо вызвать метод .render().

const rt = this.add.renderTexture(0, 0, 400, 600);
rt.repeat('crate', null, 0, 0);
rt.render();

Разбор примера: создание двух текстур

Давайте построчно разберём код из функции create в предоставленном примере.

Сначала создаются две текстуры, занимающие левую и правую половины экрана (800x600).

const rt1 = this.add.renderTexture(0, 0, 400, 600).setOrigin(0, 0);
const rt2 = this.add.renderTexture(400, 0, 400, 600).setOrigin(0, 0);

Метод .setOrigin(0, 0) устанавливает точку привязки (origin) текстуры в её левый верхний угол. Это гарантирует, что текстура начнёт рисоваться ровно с переданных координат (0,0 и 400,0).

Затем каждая текстура заполняется своим паттерном. Первая использует спрайт ящика ('crate'), вторая — растровое изображение ('raster').

rt1.repeat('crate', null, 0, 0).render();
rt2.repeat('raster', null, 0, 0).render();

Обратите внимание на цепочку вызовов: repeat возвращает ссылку на тот же объект RenderTexture, что позволяет сразу вызвать render(). После вызова render() текстуры отображаются на экране.

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

Использование RenderTexture.repeat — это не только для статичных фонов. Рассмотрим сценарии:

1. **Динамические фоны:** Можно менять ключ текстуры или её размеры в реальном времени в ответ на действия игрока (смена уровня, времени суток). 2. **Создание крупных объектов:** Сгенерировать текстуру для большого составного объекта (стена из кирпичей, поле из плиток) и наложить на неё физическое тело целиком. 3. **Оптимизация рендеринга:** Один RenderTexture с тайлами代替 hundreds of individual sprite objects drastically reduces the draw calls for the GPU, which is critical for mobile or web games.

Важное ограничение: содержимое RenderTexture статично после вызова render(). Если нужно анимировать отдельный тайл внутри текстуры, придётся перерисовывать всю текстуру заново. Для часто меняющихся композиций это может быть наоборот, затратно. Используйте этот подход для элементов, которые меняются редко.

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

Метод repeat объекта RenderTexture — мощный и простой инструмент для создания бесшовных, повторяющихся текстур в Phaser. Он избавляет от ручного размещения множества спрайтов и положительно влияет на производительность. **Идеи для экспериментов:** 1. Попробуйте передать в параметры `xиyметодаrepeat` значения, отличные от нуля, чтобы сместить узор. 2. Создайте текстуру, которая заполняется двумя разными изображениями, вызвав repeat дважды с разными ключами перед одним render. 3. Используйте RenderTexture как маску или наложите на неё шейдер для создания эффектов параллакса или свечения у сгенерированного фона.