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

Анимация — ключевой элемент игрового процесса, и выбор правильного инструмента влияет на плавность и контроль. Этот пример демонстрирует, как настраивать и сравнивать встроенную систему твинов Phaser с популярной библиотекой GSAP. Вы научитесь управлять задержками, повторами и отслеживать производительность, чтобы выбирать оптимальный подход для своих проектов.

Версия 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.script('gsap', 'js/gsap.js');
        this.load.image('block', 'assets/sprites/crate.png');
    }

    create ()
    {
        this.image1 = this.add.image(100, 200, 'block');
        this.image2 = this.add.image(100, 400, 'block');

        this.debug = this.add.graphics();

        this.debug.fillStyle(0xffffff);
        this.debug.fillRect(100-32, 0, 2, 600);
        this.debug.fillRect(700+32, 0, 2, 600);

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

            let now = performance.now();
            let start = now;

            this.tweens.add({
                targets: this.image1,
                x: 700,
                delay: 500,
                repeat: 4,
                hold: 500,
                ease: 'linear',
                duration: 1000,
                onRepeat: () => {
                    let cur = performance.now();
                    console.log('Phaser repeat', cur - now);
                    now = cur;
                },
                onComplete: () => {
                    let cur = performance.now();
                    console.log('Phaser complete', cur);
                    console.log('Phaser duration', cur - start);
                },
            });

            gsap.to(this.image2, {
                x: 700,
                repeat: 8,
                repeatDelay: 0.5,
                duration: 0.5,
                ease: 'linear',
                onComplete: () => {
                    console.log('GSAP', performance.now());
                },
            });

        });
    }

    update ()
    {
        this.debug.fillRect(this.image1.x, this.image1.y, 2, 2);
        this.debug.fillRect(this.image2.x, this.image2.y, 2, 2);
    }
}

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

const game = new Phaser.Game(config);

Загрузка ресурсов и скриптов

В методе preload загружаются необходимые ресурсы. Обратите внимание на загрузку внешнего скрипта GSAP. Это нужно для сравнения двух систем анимации.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.script('gsap', 'js/gsap.js');
this.load.image('block', 'assets/sprites/crate.png');

Создание сцены и отладка

В create создаются два спрайта и графический объект для визуализации пути. Белые линии по краям задают границы движения.

this.image1 = this.add.image(100, 200, 'block');
this.image2 = this.add.image(100, 400, 'block');

this.debug = this.add.graphics();
this.debug.fillStyle(0xffffff);
this.debug.fillRect(100-32, 0, 2, 600);
this.debug.fillRect(700+32, 0, 2, 600);

Настройка твина Phaser

Твин Phaser настраивается через this.tweens.add. Ключевые параметры: delay (задержка перед стартом), repeat (количество повторов) и hold (пауза между повторами). Callback-функции onRepeat и onComplete позволяют логировать время выполнения.

this.tweens.add({
    targets: this.image1,
    x: 700,
    delay: 500,
    repeat: 4,
    hold: 500,
    ease: 'linear',
    duration: 1000,
    onRepeat: () => {
        let cur = performance.now();
        console.log('Phaser repeat', cur - now);
        now = cur;
    },
    onComplete: () => {
        let cur = performance.now();
        console.log('Phaser complete', cur);
        console.log('Phaser duration', cur - start);
    },
});

Настройка твина GSAP

GSAP использует другой синтаксис. Параметр repeat указывает общее количество циклов (включая первый), а repeatDelay — задержку между повторами. Обратите внимание на разницу в логике подсчёта повторов по сравнению с Phaser.

gsap.to(this.image2, {
    x: 700,
    repeat: 8,
    repeatDelay: 0.5,
    duration: 0.5,
    ease: 'linear',
    onComplete: () => {
        console.log('GSAP', performance.now());
    },
});

Визуализация траектории в реальном времени

Метод update вызывается каждый кадр. Он рисует маленькие точки по текущим координатам спрайтов, создавая эффект следа. Это помогает визуально сравнить плавность и синхронность анимаций.

this.debug.fillRect(this.image1.x, this.image1.y, 2, 2);
this.debug.fillRect(this.image2.x, this.image2.y, 2, 2);

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

Phaser предоставляет мощную встроенную систему твинов, интегрированную в игровой цикл, в то время как GSAP предлагает альтернативный синтаксис и может быть полезен для сложных последовательностей. Экспериментируйте: попробуйте разные easing-функции, комбинируйте анимации свойств (scale, rotation) и измеряйте производительность на мобильных устройствах.