О чем этот пример
Создание визуально привлекательных текстовых эффектов — ключ к удержанию внимания игрока. В этой статье мы разберем, как в Phaser оживить надписи, заставив их цвета плавно перетекать по всему радужному спектру. Вы научитесь работать с цветовыми моделями, применять градиентные оттенки к тексту и создавать простые, но эффектные анимации без использования спрайтов или текстур.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
this.i = 0;
}
create ()
{
this.hsv = Phaser.Display.Color.HSVColorWheel();
// Rainbow Text
this.text1 = this.add.text(50, 100, 'Rainbow Text', { font: "74px Arial Black", fill: "#fff" });
this.text1.setStroke('#00f', 16);
this.text1.setShadow(2, 2, "#333333", 2, true, true);
// Rainbow Stroke
this.text2 = this.add.text(50, 300, 'Rainbow Stroke', { font: "74px Arial Black", fill: "#000" });
this.text2.setStroke('#fff', 16);
this.text2.setShadow(2, 2, "#333333", 2, true, true);
}
update ()
{
const top = this.hsv[this.i].color;
const bottom = this.hsv[359 - this.i].color;
this.text1.setTint(top, top, bottom, bottom);
this.text2.setTint(top, bottom, top, bottom);
this.i++;
if (this.i === 360)
{
this.i = 0;
}
}
}
const config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка цветовой палитры
В основе анимации лежит заранее сгенерированный массив из 360 цветов, который представляет собой полный цветовой круг. Phaser предоставляет для этого удобный статический метод.
this.hsv = Phaser.Display.Color.HSVColorWheel();
Вызов Phaser.Display.Color.HSVColorWheel() создает массив объектов. Каждый объект содержит цвет в формате RGB (color) и соответствующие значения HSV (оттенок, насыщенность, яркость). Индекс элемента в массиве (от 0 до 359) напрямую соответствует углу на цветовом круге. Это дает нам готовую палитру для плавного перебора всех оттенков радуги.
Создание текстовых объектов
В примере создаются два текстовых блока с разными стилями, чтобы продемонстрировать различные варианты окрашивания.
// Rainbow Text
this.text1 = this.add.text(50, 100, 'Rainbow Text', { font: "74px Arial Black", fill: "#fff" });
this.text1.setStroke('#00f', 16);
this.text1.setShadow(2, 2, "#333333", 2, true, true);
// Rainbow Stroke
this.text2 = this.add.text(50, 300, 'Rainbow Stroke', { font: "74px Arial Black", fill: "#000" });
this.text2.setStroke('#fff', 16);
this.text2.setShadow(2, 2, "#333333", 2, true, true);
Первый текст (text1) имеет белую заливку (fill: "#fff") и синюю обводку (setStroke('#00f', 16)). Второй (text2) — наоборот, черную заливку и белую обводку. Оба используют тень для объема. Исходные цвета (fill и stroke) будут перезаписаны в цикле анимации с помощью метода setTint().
Магия метода setTint()
Ключевой метод для анимации — setTint(topLeft, topRight, bottomLeft, bottomRight). Он применяет оттенок (тинт) к каждому из четырех углов игрового объекта (текста в нашем случае), создавая градиентную заливку. Цвета смешиваются между углами.
const top = this.hsv[this.i].color;
const bottom = this.hsv[359 - this.i].color;
this.text1.setTint(top, top, bottom, bottom);
this.text2.setTint(top, bottom, top, bottom);
В коде мы берем два цвета из нашей палитры: top — цвет по текущему индексу `i,bottom— цвет с противоположной стороны круга (индекс359 - i`).
- Для text1 задается вертикальный градиент: оба верхних угла — цвет top, оба нижних — bottom.
- Для text2 задается более сложный паттерн: верхний левый и нижний правый — top, верхний правый и нижний левый — bottom, что создает диагональный или крестообразный эффект.
Важно: setTint полностью заменяет исходные цвета текста (fill и stroke), игнорируя их.
Цикл анимации в update()
Анимация реализуется в методе update(), который вызывается на каждом кадре. Мы инкрементируем индекс `i`, чтобы перемещаться по цветовому кругу, и сбрасываем его, когда проходим полный цикл.
update ()
{
// ... (расчет top, bottom и вызов setTint) ...
this.i++;
if (this.i === 360)
{
this.i = 0;
}
}
Поскольку массив hsv содержит ровно 360 элементов, увеличение `iот 0 до 359 обеспечивает плавный переход через все оттенки. Сброс на 0 замыкает цикл, делая анимацию бесконечной. Использование противоположного цвета (359 - i`) гарантирует, что градиент всегда будет контрастным и динамичным.
Что попробовать дальше
Используя Phaser.Display.Color.HSVColorWheel() и setTint(), вы можете легко добавлять сложные цветовые переходы к любому игровому объекту, поддерживающему тинтирование — не только к тексту, но и к изображениям или спрайтам. Для экспериментов попробуйте изменить логику выбора цветов: например, использовать не противоположные, а соседние оттенки для более плавного градиента, или анимировать только обводку, оставив заливку static. Также можно привязать скорость изменения цвета (this.i++) к игровому времени для независимости от частоты кадров.
