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

Создание плавных числовых анимаций — ключевой элемент геймдева для отображения прогресса, очков, здоровья или таймеров. В Phaser для этого есть специальный инструмент — Counter Tween. В отличие от обычного твина, который анимирует свойства объекта, Counter Tween работает напрямую с числовым диапазоном, что делает его идеальным для динамического обновления текста или любых других значений в реальном времени. В этой статье разберем простой пример, показывающий, как создать анимацию счета от 0 до 100, привязать ее к пользовательскому вводу и выводить детальную информацию о ходе выполнения твина на экран.

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

Живой запуск

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

Исходный код


var text;
var tween;

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

    create() {
        text = this.add.text(30, 20, '0', { font: '42px Courier', fill: '#00ff00' });

        //  A 'Counter' tween is a special type of tween which doesn't have a target.
        //  Instead it allows you to tween between 2 numeric values. The default values
        //  are 0 to 1, but can be set to anything. You can use the tweened value via
        //  `tween.getValue()` for the duration of the tween.

        tween = this.tweens.addCounter({
            from: 0,
            to: 100,
            duration: 5000,
            paused: true
        });

        this.input.once('pointerdown', () => {
            tween.resume();
        });
    }

    update() {
        text.setText([
            'Value: ' + tween.getValue(),
            'Progress: ' + tween.totalProgress,
            'Elapsed: ' + tween.totalElapsed,
            'Duration: ' + tween.totalDuration
        ]);
    }
}

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

const game = new Phaser.Game(config);

Что такое Counter Tween и зачем он нужен

Counter Tween — это особый тип твина в Phaser. Его главное отличие в том, что у него нет целевого игрового объекта (target). Вместо этого он анимирует переход между двумя числами. По умолчанию это значения от 0 до 1, но диапазон можно задать любой.

Основное применение — получение плавно меняющегося числового значения в течение времени анимации через метод tween.getValue(). Это значение можно использовать для: * Динамического обновления текста (счет, таймер). * Расчетов (плавное изменение силы, прозрачности, размера нестандартным способом). * Создания кастомных прогресс-баров.

В нашем примере твин создается в состоянии paused: true, то есть не запускается автоматически, а ждет команды пользователя.

Создание сцены и текстового поля

Первым делом в методе create() создается текстовый объект, который будет отображать текущие значения. Мы размещаем его в координатах (30, 20) и задаем стиль.

text = this.add.text(30, 20, '0', { font: '42px Courier', fill: '#00ff00' });

Здесь text — глобальная переменная, чтобы быть доступной и в методе update(). В качестве начального значения отображается '0'.

Настройка и запуск Counter Tween

Сердце примера — создание самого Counter Tween. Мы используем менеджер твинов сцены this.tweens и метод addCounter().

tween = this.tweens.addCounter({
    from: 0,
    to: 100,
    duration: 5000,
    paused: true
});

* from: 0 — начальное значение анимации. * to: 100 — конечное значение. * duration: 5000 — длительность анимации в миллисекундах (5 секунд). * paused: true — твин создается в приостановленном состоянии.

Запуск твина привязан к событию клика (или касания) через систему ввода Phaser:

this.input.once('pointerdown', () => {
    tween.resume();
});

Метод once гарантирует, что обработчик сработает только один раз. При клике вызывается tween.resume(), и анимация начинает выполнение с того места, где она была приостановлена (в нашем случае — с самого начала).

Обновление данных в реальном времени

Чтобы видеть результат анимации, нам нужно постоянно обновлять текстовое поле. Это делается в методе update(), который вызывается на каждом кадре игры.

update() {
    text.setText([
        'Value: ' + tween.getValue(),
        'Progress: ' + tween.totalProgress,
        'Elapsed: ' + tween.totalElapsed,
        'Duration: ' + tween.totalDuration
    ]);
}

Здесь мы формируем массив строк, который setText() отобразит с переносами: 1. tween.getValue() — самое важное: текущее анимируемое число (между 0 и 100). 2. tween.totalProgress — прогресс твина от 0 (начало) до 1 (конец). 3. tween.totalElapsed — прошедшее время с начала твина в миллисекундах. 4. tween.totalDuration — общая длительность твина (у нас это 5000).

Таким образом, во время анимации мы видим, как все эти значения изменяются в реальном времени.

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

Counter Tween в Phaser — это мощный и гибкий инструмент для анимации чисто числовых значений. Он отлично подходит для создания счетчиков очков, плавного заполнения шкал или любых других элементов интерфейса, где нужно показать изменение числа. **Идеи для экспериментов:** * Измените параметры ease в конфигурации твина (например, на 'Bounce.Out'), чтобы сделать анимацию счета более «игровой». * Свяжите tween.getValue() не только с текстом, но и, например, с шириной графического прямоугольника, чтобы создать кастомный прогресс-бар. * Используйте событие onUpdate твина для вызова сложной логики на каждом шаге анимации. * Создайте цепочку твинов с помощью chain(), чтобы счет сначала быстро рос, а потом замедлялся.