О чем этот пример
При разработке игр иногда требуется создать эффект «шлейфа» или «следа» за движущимися объектами, не перерисовывая весь кадр. В Phaser 3 за это отвечают два ключевых свойства конфигурации: `clearBeforeRender` и `preserveDrawingBuffer`. Эта статья наглядно показывает, как, отключив очистку холста перед отрисовкой, можно создать стильный визуальный эффект для анимированных спрайтов, который легко адаптировать под различные игровые механики.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.spritesheet('fish', 'assets/sprites/fish-136x80.png', { frameWidth: 136, frameHeight: 80 });
}
create ()
{
const image1 = this.add.image(100, 80, 'fish', 0);
const image2 = this.add.image(100, 180, 'fish', 1);
const image3 = this.add.image(100, 280, 'fish', 2);
const image4 = this.add.image(100, 380, 'fish', 1);
const image5 = this.add.image(100, 480, 'fish', 0);
const tween = this.tweens.add({
targets: [ image1, image2, image3, image4, image5 ],
x: 700,
duration: 4000,
ease: 'Sine.easeInOut',
flipX: true,
yoyo: true,
repeat: -1,
delay: function (target, key, value, targetIndex)
{
return targetIndex * 1000;
}
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
clearBeforeRender: false,
preserveDrawingBuffer: true,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Зачем отключать очистку холста?
По умолчанию Phaser перед каждым кадром полностью очищает холст (clearBeforeRender: true). Это стандартное поведение для большинства игр, где сцена полностью перерисовывается 60 раз в секунду.
Однако, если установить clearBeforeRender: false, холст очищаться не будет. Новые кадры будут рисоваться поверх старых. Чтобы это работало, необходимо также включить preserveDrawingBuffer: true. Это свойство WebGL-рендерера (и Canvas) запрещает браузеру очищать буфер кадра. Без этой настройки clearBeforeRender: false может игнорироваться.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
clearBeforeRender: false,
preserveDrawingBuffer: true,
parent: 'phaser-example',
scene: Example
};
Подготовка сцены и создание объектов
В методе preload() загружается спрайтшит, содержащий несколько кадров одной анимации. Используется this.load.setBaseURL() для указания базового пути, что удобно для загрузки ресурсов из удаленного хранилища.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.spritesheet('fish', 'assets/sprites/fish-136x80.png', { frameWidth: 136, frameHeight: 80 });
}
В create() создается группа из пяти спрайтов с изображением рыбы. Каждому спрайту передается разный индекс кадра из спрайтшита (0, 1, 2, 1, 0), что создает визуальное разнообразие.
create ()
{
const image1 = this.add.image(100, 80, 'fish', 0);
const image2 = this.add.image(100, 180, 'fish', 1);
const image3 = this.add.image(100, 280, 'fish', 2);
const image4 = this.add.image(100, 380, 'fish', 1);
const image5 = this.add.image(100, 480, 'fish', 0);
}
Настройка анимации с задержкой
Для всех пяти спрайтов создается один твин с помощью this.tweens.add(). Основная задача твина — плавно перемещать объекты по оси X.
const tween = this.tweens.add({
targets: [ image1, image2, image3, image4, image5 ],
x: 700,
duration: 4000,
ease: 'Sine.easeInOut',
flipX: true,
yoyo: true,
repeat: -1,
delay: function (target, key, value, targetIndex)
{
return targetIndex * 1000;
}
});
Ключевые параметры:
* yoyo: true — анимация проигрывается в обратном порядке.
* repeat: -1 — бесконечное повторение.
* flipX: true — спрайт зеркально отражается по горизонтали при движении в обратную сторону.
* Функция delay задает задержку для каждого спрайта в массиве targets, основываясь на его индексе (targetIndex * 1000 мс). Это создает эффект «волны» или «каравана», где рыбы начинают движение не одновременно, а одна за другой.
Итоговый визуальный эффект
Сочетание настроек рендерера и анимации дает следующий результат: поскольку холст не очищается, каждый кадр движения рыбы остается на экране. Из-за задержки в старте анимации у каждой рыбы свой «хвост» из предыдущих позиций. Вместе они формируют сложные переплетающиеся шлейфы, похожие на следы в воде или световые трассы.
Эффект является накопительным. Со временем холст может полностью заполниться рисунком, так как старые следы никуда не исчезают. Это важно учитывать при проектировании геймплея.
Что попробовать дальше
Использование clearBeforeRender: false и preserveDrawingBuffer: true открывает путь к нестандартным визуальным эффектам в Phaser 3, таким как шлейфы, следы, временные порталы или мазки кисти. Для экспериментов попробуйте изменить alpha (прозрачность) спрайтов, чтобы следы постепенно исчезали, или добавьте частицы в точках предыдущих позиций объекта. Также можно управлять этими настройками динамически, включая и выключая очистку холста в runtime для определенных игровых событий.
