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

Загрузка SVG-графики в Phaser может быть неочевидной: по умолчанию изображение загружается с оригинальными размерами, что не всегда удобно. В этой статье мы разберём, как управлять размером SVG при загрузке, чтобы сразу получать ресурс нужного разрешения. Это особенно полезно для создания адаптивных интерфейсов, иконок и векторной графики в играх, когда нужно избежать лишних операций масштабирования в коде.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        //  The original svg size is 104x97
        this.load.svg('cartman', 'assets/svg/cartman.svg');

        //  This svg will be loaded in using the new size given
        this.load.svg('cartman2', 'assets/svg/cartman.svg', { width: 416, height: 388 });
    }

    create ()
    {
        this.add.image(200, 300, 'cartman').setScale(2.6);

        this.add.image(600, 300, 'cartman2');
    }
}

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

const game = new Phaser.Game(config);

Проблема загрузки SVG по умолчанию

По умолчанию метод this.load.svg() загружает SVG-файл с его исходными размерами, которые прописаны внутри файла. В нашем примере оригинальный размер картинки — 104x97 пикселей.

Если использовать изображение как есть, для увеличения придётся применять setScale(), что может привести к потере качества или неоптимальной работе с текстурами.

this.load.svg('cartman', 'assets/svg/cartman.svg');

Указание фиксированного размера при загрузке

Третий параметр метода this.load.svg() принимает объект конфигурации, где можно задать width и height. Phaser растрирует SVG сразу в указанный размер, и изображение будет загружено как текстура с этими размерами.

Это удобно, когда вы заранее знаете, какого размера нужна графика в игре. Например, для иконки размером 416x388 пикселей:

this.load.svg('cartman2', 'assets/svg/cartman.svg', { width: 416, height: 388 });

Сравнение результатов в сцене

После загрузки оба изображения добавляются в сцену. Первое (cartman) загружено с оригинальным размером 104x97, поэтому для визуального соответствия второму его приходится масштабировать в 2.6 раза.

Второе изображение (cartman2) уже имеет нужный размер 416x388, поэтому добавляется без масштабирования. Обратите внимание: координаты центров изображений одинаковы, но их визуальный размер совпадает.

this.add.image(200, 300, 'cartman').setScale(2.6);
this.add.image(600, 300, 'cartman2');

Важные нюансы и производительность

Указание размера при загрузке не только упрощает код, но и может влиять на производительность. Текстура создаётся сразу в нужном разрешении, что уменьшает вычисления при рендеринге.

Однако помните: увеличение размера в 4 раза (как в примере) приведёт к увеличению занимаемой видеопамяти в 16 раз (по площади). Планируйте размеры обдуманно.

Также этот метод не поддерживает динамическое изменение размера после загрузки — только при первоначальной загрузке через preload.

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

Использование параметра { width, height } в this.load.svg() даёт прямой контроль над размером векторной графики, упрощая дальнейшую работу с ней в игре. Для экспериментов попробуйте: загрузить один SVG в нескольких размерах как разные текстуры; комбинировать SVG с разными размерами для адаптивного интерфейса; проверить, как меняется качество при сильном увеличении размера при загрузке.