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

Создание плавных и визуально приятных анимаций — ключевой элемент геймдизайна. В Phaser для этого используется система Tween с easing-функциями, которые контролируют ускорение и замедление движения. В этой статье мы разберем на практическом примере, как работают три основных варианта квадрической (Quartic) функции плавности: `quart.in`, `quart.out` и `quart.inout`. Понимание этих механизмов позволит вам оживить игровые объекты, сделав их движение более естественным и цепляющим взгляд.

Версия 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('ufo1', 'assets/tweens/ufo1.png');
        this.load.image('ufo2', 'assets/tweens/ufo2.png');
        this.load.image('ufo3', 'assets/tweens/ufo3.png');
    }

    create ()
    {
        this.add.image(400, 300, 'bg');
        this.add.text(20, 20, 'Quartic Ease').setFontSize(32).setShadow(2, 2);

        this.add.text(750, 70, 'Quart.in').setShadow(2, 2).setOrigin(1, 0);
        this.add.text(750, 255, 'Quart.out').setShadow(2, 2).setOrigin(1, 0);
        this.add.text(750, 440, 'Quart.inOut').setShadow(2, 2).setOrigin(1, 0);

        const ufo1 = this.add.image(100, 140, 'ufo1');
        const ufo2 = this.add.image(100, 325, 'ufo2');
        const ufo3 = this.add.image(100, 510, 'ufo3');

        this.tweens.add({
            targets: ufo1,
            x: 700,
            duration: 2000,
            repeat: -1,
            hold: 500,
            repeatDelay: 500,
            ease: 'quart.in'
        });

        this.tweens.add({
            targets: ufo2,
            x: 700,
            duration: 2000,
            repeat: -1,
            hold: 500,
            repeatDelay: 500,
            ease: 'quart.out'
        });

        this.tweens.add({
            targets: ufo3,
            x: 700,
            duration: 2000,
            repeat: -1,
            hold: 500,
            repeatDelay: 500,
            ease: 'quart.inout'
        });
    }
}

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

const game = new Phaser.Game(config);

Что такое easing и зачем он нужен?

Easing-функции (функции плавности) определяют нелинейный характер анимации. Вместо равномерного перемещения объекта из точки А в точку Б, они позволяют задать ускорение в начале, замедление в конце или комбинацию обоих эффектов. Это имитирует законы физики (например, инерцию) и делает движение объектов в игре более живым и правдоподобным.

В примере используются три варианта квадрической функции Quart, которая обеспечивает более выраженный эффект ускорения/замедления по сравнению с квадратичной (Quad) или кубической (Cubic).

Разбор сцены и загрузки ресурсов

Код определяет стандартную сцену Phaser. В методе preload загружаются изображения: фон и три разные текстуры НЛО, которые будут нашими анимируемыми объектами.

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

В методе create сначала добавляется фон и текстовые метки, объясняющие, какая функция плавности где используется. Затем создаются три спрайта НЛО на разной высоте.

const ufo1 = this.add.image(100, 140, 'ufo1');
const ufo2 = this.add.image(100, 325, 'ufo2');
const ufo3 = this.add.image(100, 510, 'ufo3');

Создание Tween с функцией Quart.in

Первый твин применяется к ufo1 с параметром ease: 'quart.in'. Функция in означает, что эффект плавности применяется к *началу* анимации. Объект начинает движение с ускорения (медленно, затем быстро), но останавливается резко, без замедления.

this.tweens.add({
    targets: ufo1,
    x: 700,
    duration: 2000,
    repeat: -1,
    hold: 500,
    repeatDelay: 500,
    ease: 'quart.in'
});

Параметры твина: * targets: объект для анимации. * `x`: целевое значение свойства (перемещение вправо). * duration: длительность одного цикла (2000 мс). * repeat: -1: бесконечное повторение. * hold: пауза в 500 мс в *конечной* точке перед повтором. * repeatDelay: дополнительная пауза в 500 мс после hold перед началом нового цикла.

Сочетание hold и repeatDelay создает четкую паузу, позволяющую наблюдать разницу в характере остановки у разных easing-функций.

Создание Tween с функцией Quart.out

Второй твин использует ease: 'quart.out'. Это противоположность in. Объект ufo2 начинает движение резко, без ускорения, но к концу пути плавно замедляется.

this.tweens.add({
    targets: ufo2,
    x: 700,
    duration: 2000,
    repeat: -1,
    hold: 500,
    repeatDelay: 500,
    ease: 'quart.out'
});

Визуально это похоже на движение объекта, который «въезжает» в точку назначения. Эффект out идеально подходит для анимаций завершения действия, скрытия UI-элементов или мягкой посадки.

Создание Tween с функцией Quart.inOut

Третий твин применяет ease: 'quart.inout' (обратите внимание на написание в нижнем регистре). Это комбинированная функция, которая применяет эффект и к началу, и к концу анимации.

this.tweens.add({
    targets: ufo3,
    x: 700,
    duration: 2000,
    repeat: -1,
    hold: 500,
    repeatDelay: 500,
    ease: 'quart.inout'
});

Объект ufo3 начинает движение с плавного ускорения и завершает плавным замедлением. Это создает самый естественный и гармоничный тип движения, который часто используется для перемещения персонажей, камеры или плавного появления объектов.

Конфигурация игры и запуск

Весь пример завершается стандартной конфигурацией игры Phaser и ее инициализацией. Ключевые параметры: * width и height: определяют размер игрового холста (800x600). * scene: указывает класс, который будет использоваться в качестве основной сцены.

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

const game = new Phaser.Game(config);

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

Использование easing-функций — простой, но мощный способ значительно улучшить качество анимаций в вашей игре. На примере Quart мы увидели, как in, out и inout влияют на восприятие движения. Для экспериментов попробуйте: 1. Заменить quart на другие функции: sine, quad, cubic, expo. 2. Анимировать другие свойства, например scale или alpha, с разными функциями плавности. 3. Создать цепочку твинов с разными ease для одного объекта, чтобы смоделировать сложную траекторию. Сочетание длительности, задержек и правильной функции плавности — ваш ключ к созданию профессиональной динамики.