О чем этот пример
Визуальные эффекты — мощный инструмент для привлечения внимания игрока. Часто нужно подсветить важный объект, например, подобранный артефакт, активную способность или персонажа под действием баффа. В Phaser для этого есть встроенный фильтр Key. Эта статья на практическом примере покажет, как с помощью фильтра Key изменить определённый цвет на спрайте, оставив остальное изображение нетронутым. Вы узнаете, как инициализировать фильтр, настраивать его параметры и применять анимацию к обработанным объектам, создавая динамичные и выразительные сцены.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
unkeyed;
keyed;
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('atlas', 'assets/atlas/trimsheet/explosion-notrim.png');
}
create ()
{
this.unkeyed = this.add.image(640, 360, 'atlas').setScale(2);
this.keyed = this.add.image(640, 360, 'atlas').setScale(2).enableFilters();
this.keyed.filters.internal.addKey({ color: 0xe404f8 });
this.tweens.chain({
targets: this.unkeyed,
loop: -1,
loopDelay: 1000,
tweens: [
{
scaleX: 1.9,
scaleY: 1.9,
ease: 'Quad.inout',
duration: 1000
},
{
x: 320,
ease: 'Quad.inout',
duration: 1000
},
{
x: 640,
ease: 'Quad.inout',
duration: 1000
},
{
scaleX: 2,
scaleY: 2,
ease: 'Quad.inout',
duration: 1000
},
]
});
this.tweens.chain({
targets: this.keyed,
loop: -1,
loopDelay: 1000,
tweens: [
{
scaleX: 2.1,
scaleY: 2.1,
ease: 'Quad.inout',
duration: 1000
},
{
x: 960,
ease: 'Quad.inout',
duration: 1000
},
{
x: 640,
ease: 'Quad.inout',
duration: 1000
},
{
scaleX: 2,
scaleY: 2,
ease: 'Quad.inout',
duration: 1000
},
]
});
}
}
const config = {
type: Phaser.WEBGL,
width: 1280,
height: 720,
backgroundColor: '#2d3440',
smoothPixelArt: true,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что делает фильтр Key?
Фильтр Key (также известный как chroma key) заменяет указанный цвет на прозрачность или другой оттенок. В игровой разработке это отличный способ визуально выделить объект, не создавая для него отдельную текстуру.
В предоставленном примере одна и та же текстура взрыва используется дважды: в обычном виде и с применённым фильтром. Фильтр настроен на работу с цветом 0xe404f8 (ярко-розовый), который присутствует в текстуре атласа. В результате часть спрайта, окрашенная в этот цвет, становится прозрачной, открывая фоновый цвет сцены (#2d3440).
Подготовка сцены и загрузка ассетов
Всё начинается с базовой настройки сцены. В методе preload загружается единственная текстура — атлас со спрайтами взрыва.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('atlas', 'assets/atlas/trimsheet/explosion-notrim.png');
}
Ключевой момент: текстура 'atlas' содержит области, залитые сплошным розовым цветом (0xe404f8). Именно эти области и будут обработаны фильтром.
Создание объектов и применение фильтра
В методе create создаются два одинаковых изображения из одной текстуры. Первое — обычное, второе — с активированным фильтром.
create ()
{
this.unkeyed = this.add.image(640, 360, 'atlas').setScale(2);
this.keyed = this.add.image(640, 360, 'atlas').setScale(2).enableFilters();
this.keyed.filters.internal.addKey({ color: 0xe404f8 });
// ... анимация
}
Разберём по шагам:
1. `this.add.image(640, 360, 'atlas').setScale(2)` — создаёт стандартный спрайт и увеличивает его в 2 раза.
2. `.enableFilters()` — этот вызов **обязателен** для объекта, если вы планируете применять к нему визуальные фильтры. Он подготавливает рендерер.
3. `this.keyed.filters.internal.addKey({ color: 0xe404f8 })` — вот где происходит магия. Мы обращаемся к внутренней системе фильтров объекта (`filters.internal`) и добавляем новый фильтр типа `Key`. Параметр `color` указывает, какой именно цвет нужно сделать прозрачным. Фильтр применяется мгновенно.
Анимация для наглядности сравнения
Чтобы эффект от фильтра был ещё заметнее, к каждому спрайту применяется своя цепочка анимаций (tweens.chain). Они двигают и масштабируют объекты в противофазе, что позволяет одновременно видеть разницу между обработанной и оригинальной версией.
this.tweens.chain({
targets: this.keyed,
loop: -1,
loopDelay: 1000,
tweens: [
{
scaleX: 2.1,
scaleY: 2.1,
ease: 'Quad.inout',
duration: 1000
},
// ... другие шаги анимации
]
});
Обратите внимание на параметры:
- loop: -1 — анимация зацикливается бесконечно.
- loopDelay: 1000 — пауза в 1 секунду между повторениями цикла.
- ease: 'Quad.inout' — функция плавности, которая обеспечивает ускорение и замедление движения, делая его более естественным.
Конфигурация игры и рендерер
Для работы фильтров в Phaser 3 критически важен правильный выбор рендерера. Фильтры, включая Key, поддерживаются только в WebGL-режиме.
const config = {
type: Phaser.WEBGL, // Важно: используем WEBGL, а не AUTO или CANVAS
width: 1280,
height: 720,
backgroundColor: '#2d3440',
smoothPixelArt: true,
parent: 'phaser-example',
scene: Example
};
Установка type: Phaser.WEBGL гарантирует, что игра будет использовать WebGL-рендерер, который необходим для аппаратного ускорения и поддержки всех визуальных эффектов, включая фильтры. Цвет фона #2d3440 специально подобран контрастным к розовому, чтобы прозрачные области фильтра были чётко видны.
Что попробовать дальше
Фильтр Key — это простой, но мощный инструмент для динамического изменения внешнего вида игровых объектов прямо во время выполнения. Он экономит ресурсы, позволяя обходиться одной текстурой для нескольких визуальных состояний.
Для экспериментов попробуйте:
1. Изменить параметр color на другой шестнадцатеричный код, чтобы «вырезать» из спрайта иные области.
2. Применить фильтр к анимированному спрайту (Sprite с несколькими кадрами) и посмотреть, как эффект работает в динамике.
3. Скомбинировать фильтр Key с другими фильтрами, например, Glow или Blur, добавив их в цепочку через filters.internal.add....
