О чем этот пример
Анимации (tweens) — это мощный инструмент для создания плавных переходов в играх на Phaser. Но что происходит внутри объекта твина? В этой статье мы разберем пример, который не только создает анимацию плавного появления изображения, но и выводит на экран все его внутренние данные. Это даст вам глубокое понимание того, как работают твины, и поможет в отладке сложных анимационных сценариев.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
let image;
let tween;
let text;
class Example extends Phaser.Scene {
constructor() {
super();
}
preload() {
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('makoto', 'assets/pics/makoto.png');
}
create() {
image = this.add.image(400, 300, 'makoto');
text = this.add.text(10, 10, '', { font: '16px Courier', fill: '#00ff00' });
tween = this.tweens.add({
targets: image,
alpha: {
from: 0,
to: 1
},
delay: 2000,
duration: 5000
});
/*
tween = this.tweens.add({
targets: image,
alpha: {
start: 0,
to: 1
},
delay: 2000,
duration: 6000
});
*/
/*
tween = this.tweens.add({
targets: image,
alpha: {
start: 0.1,
from: 1,
to: 0.1
},
delay: 2000,
duration: 2000
});
*/
}
update() {
if (tween.data) this.debugTweenData(text, tween.data[0]);
}
debugTweenData(text, tweenData) {
var output = [];
var TDStates = [
'CREATED',
'INIT',
'DELAY',
'OFFSET_DELAY',
'PENDING_RENDER',
'PLAYING_FORWARD',
'PLAYING_BACKWARD',
'HOLD_DELAY',
'REPEAT_DELAY',
'COMPLETE'
];
output.push(tweenData.key);
output.push('--------');
output.push('State: ' + TDStates[tweenData.state]);
output.push('Start: ' + tweenData.start);
output.push('Current: ' + tweenData.current);
output.push('End: ' + tweenData.end);
output.push('Progress: ' + tweenData.progress);
output.push('Elapsed: ' + tweenData.elapsed);
output.push('Duration: ' + tweenData.duration);
output.push('Total Duration: ' + tweenData.totalDuration);
output.push('Delay: ' + tweenData.delay);
output.push('Yoyo: ' + tweenData.yoyo);
output.push('Hold: ' + tweenData.hold);
output.push('Repeat: ' + tweenData.repeat);
output.push('Repeat Counter: ' + tweenData.repeatCounter);
output.push('Repeat Delay: ' + tweenData.repeatDelay);
text.setText(output);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Создание базового твина: от прозрачного к видимому
Ключевой элемент примера — создание твина, который изменяет прозрачность (alpha) изображения от 0 (полностью прозрачно) до 1 (полная видимость).
Этот твин настраивается с помощью объекта конфигурации, передаваемого в метод this.tweens.add(). Давайте посмотрим на его параметры:
tween = this.tweens.add({
targets: image,
alpha: {
from: 0,
to: 1
},
delay: 2000,
duration: 5000
});
Здесь targets указывает на объект, который нужно анимировать — наше изображение image. Свойство alpha настраивается через вложенный объект, где from — начальное значение, а to — конечное. Параметр delay задает задержку в 2000 мс (2 секунды) перед стартом анимации, а duration определяет длительность самого перехода в 5000 мс (5 секунд).
Зачем нужна функция debugTweenData?
Сам твин работает «из коробки» — изображение плавно появляется. Но пример идет дальше: в каждом кадре (в методе update) он вызывает функцию debugTweenData, чтобы отобразить внутреннее состояние твина.
Функция принимает текстовый объект text для вывода и первый элемент массива tween.data. Этот массив содержит объекты данных для каждого целевого свойства твина (в нашем случае — только для alpha).
if (tween.data) this.debugTweenData(text, tween.data[0]);
Внутри debugTweenData формируется массив строк output, который затем отображается на экране. Это позволяет в реальном времени наблюдать за изменением таких параметров, как прогресс, состояние, задержки и счетчики повторов.
Ключевые свойства TweenData, которые стоит знать
Функция отладки выводит множество свойств объекта tweenData. Давайте разберем самые полезные из них:
* state: Текущее состояние твина (например, DELAY, PLAYING_FORWARD, COMPLETE). Состояния соответствуют константам в массиве TDStates.
* progress: Прогресс анимации от 0 (начало) до 1 (конец). Это ключевое значение для расчета промежуточных состояний.
* elapsed и duration: Прошедшее время с начала анимации и ее общая длительность.
* delay, hold, repeatDelay: Различные типы задержек, которые можно настроить в твине.
* repeat и repeatCounter: Общее число повторов и текущий счетчик.
* yoyo: Флаг, указывающий, будет ли твин проигрываться в обратном направлении после завершения.
output.push('Progress: ' + tweenData.progress);
output.push('State: ' + TDStates[tweenData.state]);
output.push('Repeat Counter: ' + tweenData.repeatCounter);
Наблюдение за этими свойствами в динамике — лучший способ понять логику работы твинов в Phaser.
Экспериментируем с конфигурацией: закомментированные варианты
В исходном коде есть два закомментированных блока, которые показывают альтернативные способы настройки. Они демонстрируют нюансы работы с параметрами start, from и to.
Первый вариант использует start вместо from. В API Phaser Tweens эти параметры часто синонимичны, но from является более явным и предпочтительным для задания начального значения.
// Вариант 1: Использование 'start'
alpha: {
start: 0,
to: 1
},
Второй вариант задает сразу три значения: start, from и to. В этом случае from переопределяет start, и анимация идет от 1 к 0.1, что может быть неочевидно с первого взгляда.
// Вариант 2: Путаница с start, from, to
alpha: {
start: 0.1,
from: 1,
to: 0.1
},
Практический совет: для ясности всегда используйте пару from и to для определения диапазона анимации.
Что попробовать дальше
Этот пример — отличная отправная точка для глубокого погружения в систему твинов Phaser 3. Используя функцию отладки, вы можете проверять состояние анимаций, точно настраивать цепочки и последовательности. Для экспериментов попробуйте
- Добавить параметры
repeat,yoyoиholdв конфиг твина и понаблюдать, как меняютсяrepeatCounterиstate - Создать несколько твинов для разных свойств (например, `x
иscale) и выводить данные для каждого из них, чтобы понять структуру массиваtween.data` - Использовать полученные данные (например,
progress) для синхронизации других игровых событий с анимацией
