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

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

Версия 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.atlas('atlas', 'assets/atlas/megaset-2.png', 'assets/atlas/megaset-2.json');
    }

    create ()
    {
        this.image1 = this.add.image(400, 150, 'atlas', 'atari400');
        this.image2 = this.add.image(400, 400, 'atlas', 'hotdog');

        //  Set the tint like this (topLeft, topRight, bottomLeft, bottomRight)
        this.image1.setTint(0xff00ff, 0xffff00, 0x0000ff, 0xff0000);

        this.image2.setTint(0x0000ff, 0xff0000, 0xff00ff, 0xffff00);
    }

    update ()
    {
        this.image1.rotation -= 0.02;
        this.image2.rotation += 0.02;
    }
}

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


const game = new Phaser.Game(config);

Загрузка атласа и создание изображений

Всё начинается с загрузки ресурсов. В методе preload мы используем this.load.atlas для загрузки таблицы спрайтов (атласа). Атлас — это один большой файл изображения и JSON-файл, описывающий координаты каждого отдельного спрайта (фрейма) внутри него. Это эффективный способ хранения графики.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.atlas('atlas', 'assets/atlas/megaset-2.png', 'assets/atlas/megaset-2.json');
}

После загрузки в методе create мы создаём два объекта изображения с помощью this.add.image. Важно указать не только ключ атласа ('atlas'), но и имя конкретного фрейма внутри него ('atari400' и 'hotdog'). Это позволяет использовать множество спрайтов из одного загруженного ресурса.

create ()
{
    this.image1 = this.add.image(400, 150, 'atlas', 'atari400');
    this.image2 = this.add.image(400, 400, 'atlas', 'hotdog');
    // ... далее применение tint
}

Метод setTint с четырьмя параметрами

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

//  Set the tint like this (topLeft, topRight, bottomLeft, bottomRight)
this.image1.setTint(0xff00ff, 0xffff00, 0x0000ff, 0xff0000);
this.image2.setTint(0x0000ff, 0xff0000, 0xff00ff, 0xffff00);

Каждый параметр отвечает за оттенок в определённом углу изображения: верхний левый, верхний правый, нижний левый, нижний правый. Phaser автоматически интерполирует (плавно смешивает) цвета между этими углами, создавая градиентную заливку. Порядок цветов в примере создаёт яркие, контрастные переходы, отлично демонстрирующие возможности метода.

Анимация для наглядности эффекта

Чтобы градиентный эффект был лучше виден под разными углами, пример добавляет простую анимацию вращения в методе update. Это стандартный игровой цикл Phaser, который выполняется каждый кадр.

update ()
{
    this.image1.rotation -= 0.02;
    this.image2.rotation += 0.02;
}

Объекты вращаются в противоположные стороны. Это позволяет наблюдать, как градиентный оттенок, "закреплённый" за углами спрайта, взаимодействует с его вращением, создавая динамичный и живой визуальный эффект. Без вращения сложный tint мог бы быть не так заметен на статичном изображении.

Структура конфигурации игры

Код завершается стандартной для Phaser 3 конфигурацией и созданием экземпляра игры. Обратите внимание, что в config.type указан Phaser.WEBGL. WebGL-рендерер обеспечивает высокую производительность при отрисовке эффектов, включая продвинутое окрашивание.

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

const game = new Phaser.Game(config);

Ключ scene указывает на наш класс Example, который становится активной сценой. Эта минимальная конфигурация — основа для запуска любого примера.

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

Метод setTint с четырьмя параметрами — это мощный и производительный инструмент для создания сложных визуальных эффектов без увеличения размера сборки игры новыми текстурами. Он открывает двери для экспериментов: попробуйте использовать близкие оттенки для симуляции рассеянного света, анимировать цвета углов для эффекта пульсации или 'заливки' спрайта цветом, а также комбинировать этот приём с режимами смешивания (setBlendMode) для получения ещё более необычных результатов.