О чем этот пример
Анимация в играх — это не только движение персонажей. Часто требуется плавно изменять числовые значения: счёт, здоровье, прогресс-бар или таймер. Прямое присваивание выглядит резко и неестественно. В этом примере мы рассмотрим мощный инструмент Phaser — `Tween` для счётчика (`addCounter`). Он позволяет создавать плавные переходы между двумя числами, делая интерфейс и игровую механику визуально приятными и профессиональными. Вы научитесь анимировать любые числовые данные, контролировать процесс и использовать результат в реальном времени.
Версия 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: 100,
to: 200,
duration: 5000,
yoyo: true
});
}
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);
Что такое Tween-счётчик и зачем он нужен?
Обычный Tween в Phaser привязан к конкретному свойству игрового объекта, например, к координате `xспрайта.Tween-счётчик (addCounter`) — это особый тип твина без явной цели. Вместо изменения свойств объекта он плавно интерполирует (переходит) между двумя заданными числами.
Это идеально для сценариев, где нужно получить изменяющееся во времени число и использовать его самостоятельно. Например: * Плавное увеличение счёта при сборе монет. * Анимация заполнения шкалы здоровья или маны. * Создание плавно меняющегося параметра для шейдера или кастомной графики. * Управление громкостью звука или прозрачностью группы объектов.
Разбор создания счётчика
Вся магия происходит в методе create. Сначала создаётся текстовый объект для отображения значений.
text = this.add.text(30, 20, '0', { font: '42px Courier', fill: '#00ff00' });
Затем создаётся сам твин-счётчик. Ключевой метод — this.tweens.addCounter(config).
tween = this.tweens.addCounter({
from: 100,
to: 200,
duration: 5000,
yoyo: true
});
Разберём параметры конфигурации:
* from: 100 — начальное значение счётчика.
* to: 200 — конечное значение.
* duration: 5000 — длительность перехода от from к to в миллисекундах (5 секунд).
* yoyo: true — опция, заставляющая твин проигрываться в обратном порядке после завершения, создавая цикл (100→200, затем 200→100).
Получение значения и мониторинг прогресса
Созданный твин работает в фоновом режиме. Чтобы использовать его текущее значение, нужно вызвать метод getValue() у объекта твина.
В методе update (вызывается каждый кадр) мы запрашиваем актуальные данные твина и отображаем их. Это демонстрирует, как можно интегрировать анимированное число в логику игры.
text.setText([
'Value: ' + tween.getValue(), // Текущее число между from и to
'Progress: ' + tween.totalProgress, // Общий прогресс твина от 0 до 1
'Elapsed: ' + tween.totalElapsed, // Сколько времени прошло (мс)
'Duration: ' + tween.totalDuration // Полная длительность цикла (мс)
]);
Важно: totalProgress, totalElapsed и totalDuration учитывают опцию yoyo. При yoyo: true полный цикл длится 10000 мс (5 сек туда + 5 сек обратно).
Практическое применение: плавный счёт
Давайте применим знания на практике. Создадим эффект плавного набора очков. Предположим, игрок заработал 1000 очков, и мы хотим, чтобы цифры на экране увеличивались не скачком, а плавно.
// В момент получения очков
let currentScore = 500;
let newScore = 1500;
// Создаём твин-счётчик от текущего значения к новому
this.scoreTween = this.tweens.addCounter({
from: currentScore,
to: newScore,
duration: 2000, // Анимация за 2 секунды
onUpdate: (tween) => {
// Каждый кадр обновляем текст счёта, округляя значение
this.scoreText.setText(`Score: ${Math.round(tween.getValue())}`);
},
onComplete: () => {
// По завершении гарантированно выставляем точное значение
currentScore = newScore;
}
});
Здесь используется callback onUpdate для обновления текста и onComplete для синхронизации логической переменной.
Что попробовать дальше
Tween-счётчик — это элегантное решение для анимации чисел, которое значительно улучшает пользовательский опыт. Он избавляет от необходимости вручную писать логику интерполяции в update. Для экспериментов попробуйте: добавить repeat для многократного повторения, использовать разные функции плавности (ease) для нелинейного изменения значения (например, ease: 'Power2'), или связать значение счётчика не только с текстом, но и со свойством scale или alpha группы объектов.
