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

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

Версия 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('face', 'assets/pics/bw-face.png');
    }

    create ()
    {
        const hsv = Phaser.Display.Color.HSVColorWheel();
        const image = this.add.image(400, 300, 'face');

        image.setTint(0xff00ff, 0xffff00, 0x0000ff, 0xff0000);

        this.input.on('pointerdown', function (pointer) {

            const a = Phaser.Math.Between(0, 359);
            const b = Phaser.Math.Between(0, 359);
            const c = Phaser.Math.Between(0, 359);
            const d = Phaser.Math.Between(0, 359);

            image.setTint(hsv[a].color, hsv[b].color, hsv[c].color, hsv[d].color);

        });
    }
}

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

const game = new Phaser.Game(config);

Суть вершинного тонирования

В графическом конвейере WebGL у каждого спрайта есть четыре вершины (верхний левый, верхний правый, нижний левый, нижний правый). Метод image.setTint() может принимать до четырех числовых значений цвета, каждое из которых применяется к соответствующей вершине изображения. Цвета интерполируются (плавно смешиваются) по поверхности спрайта, создавая градиент.

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

Код инициализации сцены

Сцена загружает черно-белое изображение, которое идеально подходит для демонстрации тонирования, так как исходные цвета не влияют на результат.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('face', 'assets/pics/bw-face.png');
}

В методе create мы создаем массив hsv — HSV-цветовой круг из 360 оттенков — и добавляем изображение в центр экрана.

create ()
{
    const hsv = Phaser.Display.Color.HSVColorWheel();
    const image = this.add.image(400, 300, 'face');
    // ...
}

Применение четырехцветного tint

Метод setTint вызывается с четырьмя аргументами — цветами в формате HEX (0xRRGGBB). Порядок аргументов соответствует вершинам: **сверху-слева, сверху-справа, снизу-слева, снизу-справа**.

image.setTint(0xff00ff, 0xffff00, 0x0000ff, 0xff0000);

Это создает четырехцветный градиент: малиновый в левом верхнем углу, желтый в правом верхнем, синий в левом нижнем и красный в правом нижнем.

Динамическая смена цветов

В примере добавлен обработчик клика мыши (pointerdown). При каждом клике генерируются четыре случайных индекса от 0 до 359, которые используются для выбора цветов из HSV-круга. Эти цвета затем применяются к вершинам изображения.

this.input.on('pointerdown', function (pointer) {
    const a = Phaser.Math.Between(0, 359);
    const b = Phaser.Math.Between(0, 359);
    const c = Phaser.Math.Between(0, 359);
    const d = Phaser.Math.Between(0, 359);
    image.setTint(hsv[a].color, hsv[b].color, hsv[c].color, hsv[d].color);
});

Функция Phaser.Math.Between возвращает случайное целое число в заданном диапазоне. Массив hsv содержит объекты со свойством color, в котором хранится числовое значение цвета.

Важность WebGL-рендера

Ключевое требование для работы вершинного тонирования — использование WebGL-рендерера. В конфигурации игры обязательно должен быть указан type: Phaser.WEBGL. При использовании Canvas-рендерера (Phaser.CANVAS) метод setTint с несколькими параметрами будет проигнорирован или применет только первый цвет.

const config = {
    type: Phaser.WEBGL, // Обязательно WEBGL
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: Example
};

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

Вершинное тонирование — это простой, но мощный инструмент для создания сложных визуальных эффектов без использования дополнительных текстур. Вы можете анимировать цвета вершин для имитации освещения, изменения времени суток или создания психоделических переходов. **Идеи для экспериментов:** 1. Свяжите цвета вершин с положением объекта на экране или его скоростью. 2. Используйте Phaser.Tweens для плавной анимации перехода между наборами цветов. 3. Примените этот метод к тайловым спрайтам (Sprite), а не только к изображениям (Image). 4. Создайте градиент, который зависит от направления движения персонажа.