О чем этот пример
При работе с визуальными эффектами в Phaser 3 разработчики часто используют системы preFX и postFX. Этот пример наглядно демонстрирует важное различие в поведении методов `clear()` для этих систем. Понимание этого нюанса поможет избежать ошибок, когда эффект внезапно не очищается, и осознанно управлять графическим конвейером объекта.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Demo extends Phaser.Scene {
constructor() {
super({
key: 'examples'
})
}
preload() {
}
create() {
var gameObject0 = CreateGameObject(this, 200, 300)
var gameObject1 = CreateGameObject(this, 400, 300)
gameObject1.preFX.addPixelate(10);
gameObject1.preFX.clear();
var gameObject2 = CreateGameObject(this, 600, 300)
gameObject2.postFX.addPixelate(10);
gameObject2.postFX.clear();
}
}
var CreateGameObject = function (scene, x, y) {
return scene.add.text(x, y, 'Phaser3\nPhaser3\nPhaser3\nPhaser3', {
fontSize: 25,
})
}
var config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: [Demo]
};
var game = new Phaser.Game(config);
Суть примера: демонстрация различий
В коде создаётся три текстовых объекта с одинаковым содержимым. На второй и третий объекты добавляется пикселизационный эффект (addPixelate(10)), а затем сразу же делается попытка его очистить с помощью метода clear(). Ключевое различие — тип эффекта: для второго объекта используется preFX, для третьего — postFX. Визуальный результат будет разным, что и является предметом изучения.
Инициализация сцены и создание объектов:
Создание объектов и настройка эффектов
Функция CreateGameObject создаёт текстовой объект с многострочным текстом. В методе create() сцены создаются три таких объекта в разных позициях по оси X.
var CreateGameObject = function (scene, x, y) {
return scene.add.text(x, y, 'Phaser3\nPhaser3\nPhaser3\nPhaser3', {
fontSize: 25,
})
}
Настройка эффектов для объектов gameObject1 и gameObject2:
Критическое различие: preFX.clear() и postFX.clear()
Здесь происходит самое важное. Для gameObject1 добавляется и сразу очищается эффект из конвейера preFX. Для gameObject2 те же действия выполняются для конвейера postFX.
// Для gameObject1 (preFX)
gameObject1.preFX.addPixelate(10);
gameObject1.preFX.clear();
// Для gameObject2 (postFX)
gameObject2.postFX.addPixelate(10);
gameObject2.postFX.clear();
Поведение будет отличаться. Эффект postFX успешно удалится, а эффект preFX — останется. Это связано с внутренним порядком обработки графического конвейера в момент вызова.
Почему так происходит? Порядок выполнения
Система preFX применяет эффекты к исходному изображению игрового объекта *до* его отрисовки. Когда вы вызываете addPixelate() и clear() в одном кадре в методе create(), система preFX может не успеть обработать команду очистки до первичного рендера. В результате эффект остаётся «запечённым» для этого кадра, и мы видим пикселизированный объект.
Система postFX работает *после* отрисовки объекта (пост-обработка). Её конвейер часто обновляется в другом порядке или в следующем кадре, поэтому немедленный вызов clear() в том же методе create() успевает удалить эффект до его применения. Объект gameObject2 будет отображён без пикселизации.
Практический вывод и решение
Если вам нужно гарантированно очистить эффект preFX, не делайте это в том же игровом цикле, где эффект был добавлен. Используйте задержку в один кадр или привяжите очистку к событию.
Пример безопасной очистки preFX через задержку:
// Добавляем эффект
gameObject.preFX.addPixelate(10);
// Очищаем его в следующем кадре
this.time.delayedCall(0, () => {
gameObject.preFX.clear();
});
Этот подход даёт системе preFX время на корректную инициализацию и последующую очистку конвейера.
Что попробовать дальше
Метод clear() для preFX и postFX в Phaser 3 может вести себя по-разному при вызове в тот же момент, когда эффект был добавлен. Для postFX очистка обычно происходит мгновенно, а для preFX может потребоваться задержка. Экспериментируйте: попробуйте очищать эффекты по клику мыши или через несколько секунд, чтобы увидеть разницу. Исследуйте, как ведут себя другие эффекты (размытие, свечение, тень) при подобной очистке.
