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

Оттенки (tint) — один из самых быстрых способов изменить визуальный стиль спрайта без загрузки дополнительных текстур. В этом примере мы разберем, как метод `setTint()` позволяет динамически окрашивать изображения, используя шестнадцатеричные коды цветов. Этот подход полезен для создания вариаций объектов (например, врагов разных цветов), визуальных эффектов или индикаторов состояния, экономя память и время на подготовку ресурсов.

Версия 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('pixel', 'assets/sprites/16x16.png');
    }

    create ()
    {
        this.add.image(300, 300, 'pixel').setTint(0xff0000);
        this.add.image(400, 300, 'pixel').setTint(0x00ff00);
        this.add.image(500, 300, 'pixel').setTint(0x0000ff);
    }
}

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

const game = new Phaser.Game(config);

Загрузка базового спрайта

Вся магия начинается с загрузки одного простого изображения — в нашем случае это белый квадрат 16x16 пикселя. Использование однотонного спрайта идеально подходит для тонирования, так как цвет будет применен равномерно и предсказуемо.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('pixel', 'assets/sprites/16x16.png');

Метод setBaseURL задает базовый путь для загрузки, а load.image регистрирует наш спрайт под ключом 'pixel'. Важно: исходный спрайт должен быть светлым (лучше белым), чтобы tint не затемнял итоговый цвет.

Создание и окрашивание изображений

В фазе create мы создаем три экземпляра одного и того же спрайта, позиционируя их по горизонтали. Ключевой момент — применение метода setTint() к каждому изображению.

this.add.image(300, 300, 'pixel').setTint(0xff0000);
this.add.image(400, 300, 'pixel').setTint(0x00ff00);
this.add.image(500, 300, 'pixel').setTint(0x0000ff);

Каждый вызов setTint принимает шестнадцатеричный код цвета: 0xff0000 (красный), 0x00ff00 (зеленый), 0x0000ff (синий). Phaser умножает цвета текселей спрайта на заданный оттенок, поэтому белый пиксель становится точно указанным цветом, а черные области остаются черными.

Как устроен метод setTint

setTint — это метод экземпляра класса Phaser.GameObjects.Image. Он работает на уровне WebGL (или Canvas) и применяет цветовую фильтрацию непосредственно при отрисовке, не изменяя исходные пиксели текстуры. Это делает операцию очень производительной.

// Можно задать несколько градиентных оттенков за один вызов
image.setTint(0xff0000, 0x00ff00, 0x0000ff, 0xffff00);

Если передать четыре цвета (как в примере выше), они будут применены к вершинам спрайта, создавая градиентный переход. В нашем же примере используется один цвет для всего изображения.

Конфигурация игры и сцены

Пример завершается стандартной для Phaser 3 настройкой. Обратите внимание, что в config указан type: Phaser.WEBGL. Tint работает и в Canvas-режиме, но WebGL обеспечивает более высокую производительность при множестве окрашенных объектов.

const config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: Example
};
const game = new Phaser.Game(config);

Класс сцены Example регистрируется в конфигурации, и движок автоматически управляет его жизненным циклом (preload, create, update).

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

Использование setTint — это эффективный прием для управления цветом спрайтов в рантайме. Поэкспериментируйте: создайте анимацию плавного изменения оттенка с помощью tween, примените градиентный tint к спрайтам сложной формы или используйте разные цвета для визуального различия фракций в стратегической игре. Помните, что этот метод не меняет текстуру, поэтому он идеален для динамических и повторяющихся эффектов.