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

Плавные и реалистичные анимации — ключ к удержанию внимания игрока. Одна из самых выразительных функций для создания движения в Phaser — это система твинов с различными функциями плавности (easing). В этой статье мы разберем, как работает ease-функция `Back`, которая позволяет анимации "откатываться" назад перед началом или после завершения основного движения, создавая эффект упругости или инерции. Это простой, но мощный способ добавить персонажам и интерфейсным элементам живость и физическую достоверность без сложных расчетов.

Версия 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, 'Back Ease').setFontSize(32).setShadow(2, 2);

        this.add.text(750, 70, 'Back.in').setShadow(2, 2).setOrigin(1, 0);
        this.add.text(750, 255, 'Back.out').setShadow(2, 2).setOrigin(1, 0);
        this.add.text(750, 440, 'Back.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: 'back.in'
        });

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

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

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

const game = new Phaser.Game(config);

Что такое Back Ease и зачем он нужен

Функция плавности Back — это один из типов easing в Phaser, который заставляет анимацию временно выходить за пределы начальной или конечной точки. Это создает иллюзию инерции, отката или небольшого "разгона". Она идеально подходит для: * Эффектов появления/исчезновения интерфейса. * Упругих ударов или толчков. * Добавления "веса" движению объектов.

В примере используются три вариации: Back.in, Back.out и Back.inOut. Каждая из них определяет, в какой части анимации произойдет этот "откат".

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

Код начинается с создания стандартного класса сцены Example. В методе preload загружаются фоновое изображение и три спрайта НЛО с удаленного сервера. Обратите внимание на использование this.load.setBaseURL для указания базового пути — это удобно для работы с ресурсами из репозитория.

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 сначала добавляется фон и текст с названием эффекта. Затем для каждого НЛО добавляются подписи, объясняющие, какой тип Back ease будет использован. Ключевой момент — позиционирование текста с помощью .setOrigin(1, 0), что выравнивает его по правому краю (originX = 1).

this.add.text(750, 70, 'Back.in').setShadow(2, 2).setOrigin(1, 0);

Создание объектов и настройка твинов

Три спрайта НЛО создаются в разных позициях по оси Y, чтобы они двигались параллельно друг другу.

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. Конфигурации идентичны, за исключением свойства ease. Все твины: * targets: Применяются к соответствующему спрайту. * x: 700: Перемещают объект по горизонтали. * duration: 2000: Длятся 2 секунды. * repeat: -1: Повторяются бесконечно. * hold: 500 и repeatDelay: 500: Делают паузу в 500 мс в конечной точке и перед каждым повторением.

Сравнение Back.in, Back.out и Back.inOut

Вот как ведут себя разные типы Back ease в анимации движения слева направо:

// Для первого НЛО: откат в начале движения
ease: 'back.in'

Back.in: Эффект "отката" происходит в **начале** анимации. НЛО сначала немного сдвинется влево (против движения), а затем начнет движение к цели. Создает ощущение, что объект "готовится" к рывку.

// Для второго НЛО: откат в конце движения
ease: 'back.out'

Back.out: Эффект "отката" происходит в **конце** анимации. НЛО долетит до точки x:700, а затем проедет чуть дальше (за нее), после чего "откатится" назад на конечную позицию. Эмулирует эффект перелета по инерции.

// Для третьего НЛО: откат в начале и в конце
ease: 'back.inout'

Back.inOut: Комбинирует оба эффекта. Анимация начинается с отката назад, а заканчивается небольшим перелетом и возвратом. Это самый выраженный и "упругий" вариант.

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

Стандартная конфигурация игры создает холст 800x600 пикселей, устанавливает темно-серый фон и указывает наш класс Example в качестве стартовой сцены.

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

const game = new Phaser.Game(config);

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

Функция Back ease — это отличный инструмент для придания анимациям в Phaser физической выразительности и игривости. Она проста в использовании: достаточно указать ее название в свойстве ease при создании твина. **Идеи для экспериментов:** 1. Попробуйте применить Back.out к всплывающим окнам (UI) при их закрытии. 2. Скомбинируйте Back.in с анимацией масштаба (scaleX, scaleY) для эффекта "сжатия перед прыжком". 3. Используйте разные значения duration, hold и repeatDelay, чтобы создать уникальный ритм движения для персонажа или врага.