Обновление текстуры спрайта во время выполнения

Для работы с библиотекой PixiJS первым шагом является создание экземпляра приложения. Он управляет рендерингом и предоставляет сцену, на которой будут размещены спрайты и контейнеры:

const app = new PIXI.Application({
    width: 800,
    height: 600,
    backgroundColor: 0x1099bb
});
document.body.appendChild(app.view);

Создание спрайта на основе текстуры выглядит следующим образом:

let texture = PIXI.Texture.from('images/initial.png');
let sprite = new PIXI.Sprite(texture);
sprite.x = 400;
sprite.y = 300;
sprite.anchor.set(0.5);
app.stage.addChild(sprite);

Ключевой момент: текстура может быть заменена на лету, что позволяет динамически изменять визуальное содержимое объекта.


Замена текстуры спрайта во время выполнения

PixiJS предоставляет простой способ изменить текстуру существующего спрайта:

let newTexture = PIXI.Texture.from('images/updated.png');
sprite.texture = newTexture;

При этом необходимо учитывать, что прежняя текстура продолжает храниться в памяти, если на неё есть ссылки. Для освобождения ресурсов рекомендуется использовать метод destroy:

sprite.texture.destroy(true);
sprite.texture = PIXI.Texture.from('images/updated.png');

Параметр true в destroy гарантирует, что ресурсы текстуры будут полностью удалены из GPU и оперативной памяти.


Асинхронная загрузка текстур

Для динамического обновления спрайтов часто требуется загружать изображения асинхронно. PixiJS Loader упрощает этот процесс:

PIXI.Loader.shared.add('dynamicImage', 'images/dynamic.png').load((loader, resources) => {
    sprite.texture = resources.dynamicImage.texture;
});

Особенности:

  • Использование общего загрузчика PIXI.Loader.shared позволяет управлять всеми ресурсами в одном месте.
  • Объект resources содержит все загруженные текстуры с доступом по ключу, указанному при добавлении.

Для повторного обновления текстуры с другим изображением достаточно снова использовать метод add и присвоение sprite.texture.


Использование BaseTexture и Texture для продвинутого контроля

PixiJS разделяет понятия BaseTexture и Texture:

  • BaseTexture хранит исходные данные изображения в GPU.
  • Texture — это обёртка над BaseTexture, позволяющая использовать отдельные регионы или анимационные спрайты.

Создание нового текстурного региона:

let base = PIXI.BaseTexture.from('images/spritesheet.png');
let frame = new PIXI.Rectangle(0, 0, 64, 64);
let regionTexture = new PIXI.Texture(base, frame);
sprite.texture = regionTexture;

Это особенно полезно для spritesheet-анимаций, когда один файл содержит несколько кадров.


Динамическая анимация с заменой текстур

Для анимационных спрайтов можно комбинировать массивы текстур и Ticker:

const textures = [
    PIXI.Texture.from('images/frame1.png'),
    PIXI.Texture.from('images/frame2.png'),
    PIXI.Texture.from('images/frame3.png')
];

let currentFrame = 0;
app.ticker.add(() => {
    sprite.texture = textures[currentFrame];
    currentFrame = (currentFrame + 1) % textures.length;
});

Особенности:

  • app.ticker синхронизирован с рендерингом PixiJS и обеспечивает плавное обновление текстуры.
  • Использование цикла % позволяет автоматически повторять анимацию.
  • Каждая текстура может быть создана из отдельных файлов или регионов spritesheet.

Оптимизация производительности при смене текстур

  • Кэширование текстур: избегать повторной загрузки одних и тех же изображений. Использовать PIXI.Texture.from только один раз и хранить ссылки.
  • Освобождение ресурсов: старые текстуры удалять при необходимости через destroy, чтобы не перегружать GPU.
  • Использование spritesheet: группировка кадров в один файл уменьшает количество загрузок и переключений текстур.
  • Минимизация перерисовки: обновление текстуры только при необходимости, а не в каждом кадре, если изображение не меняется.

Работа с RenderTexture

Для генерации текстур на лету можно использовать RenderTexture, позволяющий рендерить контейнеры в текстуру и применять её к спрайту:

let renderTexture = PIXI.RenderTexture.create({ width: 200, height: 200 });
app.renderer.render(sprite, { renderTexture });
sprite.texture = renderTexture;

Применение RenderTexture открывает возможности для:

  • динамического комбинирования нескольких спрайтов в один;
  • создания эффектов с постобработкой;
  • кэширования сложных сцен для повышения производительности.

Замена текстур на основе событий

Часто необходимо обновлять спрайт при взаимодействии:

sprite.interactive = true;
sprite.on('pointerdown', () => {
    sprite.texture = PIXI.Texture.from('images/clicked.png');
});

Возможны сценарии:

  • смена изображения при наведении курсора (pointerover, pointerout);
  • визуальная реакция на анимационные события;
  • интеграция с игровыми событиями и логикой.

Итоговые рекомендации

  • Использовать Texture.from и кэширование для экономии ресурсов.
  • Освобождать неиспользуемые текстуры через destroy.
  • Применять RenderTexture для динамического рендеринга и сложных комбинаций.
  • Использовать Loader для асинхронной загрузки при работе с большим количеством изображений.
  • Комбинировать массивы текстур с Ticker для плавной анимации.

Такой подход обеспечивает гибкость, эффективность и удобство при работе с динамическими спрайтами в PixiJS.