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

Tween (твин) в Phaser — это мощный инструмент для плавной анимации свойств игровых объектов. Часто в разработке игр нужно не просто двигать спрайт из точки А в точку Б, но и реагировать на ключевые моменты анимации: её начало, завершение, повторение или изменение направления. Именно для этого система твинов предоставляет набор callback-функций (колбэков), которые вызываются автоматически при наступлении определённых событий. Эта статья на практическом примере покажет, как использовать колбэки `onStart`, `onComplete`, `onYoyo`, `onRepeat`, `onPause` и `onResume`. Вы научитесь синхронизировать игровую логику с анимацией, например, проигрывать звук в момент разворота объекта или обновлять интерфейс при завершении движения.

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

Живой запуск

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

Исходный код


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

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('bg', 'assets/tweens/space.png');
        this.load.image('ship', 'assets/tweens/spacetank.png');
    }

    create ()
    {
        this.add.image(400, 300, 'bg');

        const ship = this.add.image(200, 300, 'ship');

        const status = this.add.text(10, 10, '', { color: '#00ff00', fontSize: 16 });

        const log = [];

        const tween = this.tweens.add({
            targets: ship,
            x: 700,
            ease: 'Power1',
            duration: 3000,
            yoyo: true,
            repeat: 2,
            flipX: true,
            onStart: () => {
                log.push('onStart');
                status.setText(log);
            },
            onComplete: () => {
                log.push('onComplete');
                status.setText(log);
            },
            onYoyo: () => {
                log.push('onYoyo');
                status.setText(log);
            },
            onRepeat: () => {
                log.push('onRepeat');
                status.setText(log);
            },
            onPause: () => {
                log.push('onPause');
                status.setText(log);
            },
            onResume: () => {
                log.push('onResume');
                status.setText(log);
            }
        });

        this.input.on('pointerdown', () => {

            if (tween.isPlaying())
            {
                tween.pause();
            }
            else
            {
                tween.resume();
            }

        });
    }
}

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

const game = new Phaser.Game(config);

Базовый твин и настройка отладки

В примере создаётся твин для движения космического корабля (ship) по оси X с возвратом (yoyo) и повторением. Чтобы визуализировать вызов колбэков, используется текстовый объект status, который отображает лог событий.

Массив log служит для накопления названий сработавших колбэков. Каждый раз, когда вызывается колбэк, его имя добавляется в массив, а затем весь лог выводится в текстовое поле с помощью status.setText(log).

const status = this.add.text(10, 10, '', { color: '#00ff00', fontSize: 16 });
const log = [];

Колбэки жизненного цикла анимации

Основные колбэки связаны с ключевыми этапами выполнения твина. Их нужно передавать как функции в конфигурационный объект при создании твина с помощью this.tweens.add().

- onStart: Срабатывает один раз при старте анимации. - onComplete: Вызывается один раз, когда вся анимация (с учётом повторов и йо-йо) полностью завершена. - onYoyo: Срабатывает каждый раз, когда твин достигает конца и начинает движение в обратную сторону (благодаря свойству yoyo: true). - onRepeat: Вызывается каждый раз, когда твин завершает один цикл и начинает его заново (кроме последнего повторения). В примере repeat: 2 означает, что анимация сыграется три раза, и onRepeat вызовется дважды.

onStart: () => {
    log.push('onStart');
    status.setText(log);
},
onYoyo: () => {
    log.push('onYoyo');
    status.setText(log);
}

Контроль воспроизведения: Pause и Resume

Phaser позволяет ставить твин на паузу и возобновлять его. В примере для этого используется обработчик клика мыши (pointerdown). При клике проверяется, проигрывается ли твин сейчас, с помощью метода tween.isPlaying(). В зависимости от результата вызывается tween.pause() или tween.resume().

Для реакции на эти действия в конфигурации твина определены колбэки onPause и onResume. Они добавляют соответствующие записи в лог.

this.input.on('pointerdown', () => {
    if (tween.isPlaying()) {
        tween.pause();
    } else {
        tween.resume();
    }
});
onPause: () => {
    log.push('onPause');
    status.setText(log);
},
onResume: () => {
    log.push('onResume');
    status.setText(log);
}

Практическое применение колбэков

Колбэки — это не просто инструмент для отладки. Вот как их можно использовать в реальной игре:

- onStart: Включить звук двигателя корабля при начале движения. - onYoyo: Изменить спрайт или проиграть анимацию разворота, когда объект меняет направление. - onComplete: Открыть проход или активировать триггер, когда платформа завершила свой путь. - onPause/onResume: Ставить и возобновлять связанные звуковые эффекты, когда игра уходит в паузу.

Главное правило: внутри колбэков вы можете вызывать любой код вашей игры — менять состояние, создавать частицы, обновлять UI.

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

Колбэки твинов в Phaser — это простой и эффективный способ сделать ваши анимации интерактивными и осмысленными. Они связывают визуальное движение с игровой логикой, позволяя создавать сложные последовательности действий. Для экспериментов попробуйте: добавить в колбэки вызовы this.sound.play(); создать цепочку твинов, где onComplete одного запускает следующий; или использовать onUpdate (не показан в примере) для непрерывной проверки условий во время анимации.