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

Визуальная обратная связь — ключевой элемент игрового опыта. Анимированный текст или интерфейс делает игру живой и отзывчивой. В Phaser для таких задач идеально подходит система Tween. На примере простой анимации «Game Over» разберем, как плавно менять размер и цвет текста, создавая выразительные эффекты без лишнего кода. Этот подход универсален: его можно использовать для титров, сообщений о бонусе, счетчиков или любого элемента UI, которому нужно добавить динамики.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
    }

    create ()
    {
        const text = this.add.text(400, 300, 'GAME OVER!', { fontFamily: 'Arial', size: 20, color: '#000' }).setOrigin(0.5, 0.5);

        this.tweens.addCounter({
            from: 0,
            to: 1,
            duration: 3000,
            yoyo: true,
            onUpdate: (tween) => {

                const v = tween.getValue();
                const c = 255 * v;

                text.setFontSize(20 + v * 64);
                text.setColor(`rgb(${c}, ${c}, ${c})`);
            }
        });
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d',
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Настройка сцены и базового текста

Вся логика анимации размещается в методе create сцены. Первым делом создается текстовый объект с помощью this.add.text. Важно правильно задать его начальные параметры и точку привязки (origin).

const text = this.add.text(400, 300, 'GAME OVER!', { fontFamily: 'Arial', size: 20, color: '#000' }).setOrigin(0.5, 0.5);

* **Координаты (400, 300):** Указывают позицию текста на экране. В данном случае это центр, так как ширина игры — 800, а высота — 600. * **Стиль текста:** Задается третьим аргументом. Мы определяем шрифт, начальный размер (20 пикселей) и черный цвет (#000). * **setOrigin(0.5, 0.5):** Этот вызов — ключевой. Он устанавливает точку привязки (anchor) текста в его геометрический центр. Это значит, что при изменении размера текст будет масштабироваться равномерно во все стороны от этой центральной точки, а не от верхнего левого угла.

Создание Tween с помощью `tweens.addCounter`

Phaser предлагает два основных типа твинов: для свойств объектов и addCounter. Последний генерирует плавно меняющееся числовое значение, которое идеально подходит для ручного управления несколькими свойствами сразу, как в нашем случае.

this.tweens.addCounter({
    from: 0,
    to: 1,
    duration: 3000,
    yoyo: true,
    onUpdate: (tween) => { /* ... */ }
});

* **from и to:** Начальное и конечное значение счётчика. Мы используем диапазон от 0 до 1 — это удобная нормализованная величина для интерполяции. * **duration:** Длительность анимации в миллисекундах (3000 мс = 3 секунды). * **yoyo: true:** Включает режим «йо-йо». После достижения конечного значения (to) анимация автоматически воспроизводится в обратном порядке. Эффект получается бесконечным и плавным.

Обработка кадра анимации в `onUpdate`

Сердце анимации — функция обратного вызова onUpdate. Она выполняется на каждом кадре твина и получает текущее значение счётчика через метод tween.getValue().

onUpdate: (tween) => {
    const v = tween.getValue(); // Значение от 0 до 1
    const c = 255 * v;          // Преобразуем в диапазон цвета (0-255)

    text.setFontSize(20 + v * 64);
    text.setColor(`rgb(${c}, ${c}, ${c})`);
}

* **tween.getValue():** Возвращает текущее значение счётчика (`v). Оно плавно меняется от 0 до 1 и обратно благодаряyoyo`. * **Расчет размера:** 20 + v * 64. Начальный размер (20) плюс переменная часть. Когда v = 1, размер станет 84 (20+64). Текст будет плавно «раздуваться» и «сдуваться». * **Расчет цвета:** 255 * v преобразует нормализованное значение в компонент цвета RGB. При v=0 цвет черный (rgb(0,0,0)), при v=1 — белый (rgb(255,255,255)). Так мы получаем одновременное изменение от черного к белому и обратно.

Конфигурация игры (config)

Это стандартная конфигурация для примера. Она создает игровое поле размером 800x600 пикселей с темно-серым фоном и инициализирует нашу сцену.

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d',
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

* **backgroundColor: '#2d2d2d':** Темный фон выбран для контраста с текстом, который меняется от черного к белому. Это делает анимацию максимально заметной.

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

Использование tweens.addCounter — мощный и гибкий приём для создания сложных анимаций, где нужно синхронно менять несколько несвязанных свойств. Экспериментируйте: попробуйте менять не только размер и цвет, но и угол поворота (text.setRotation), прозрачность (text.setAlpha) или даже подставлять значение счётчика в сам текст (text.setText('Scale: ' + v.toFixed(2))). Замените линейную интерполяцию на другие функции плавности (ease), чтобы придать анимации уникальный характер — например, эффект упругости или резкого ускорения.