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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('bunny', 'assets/sprites/bunny.png');
    }

    create ()
    {
        const layer = this.add.spriteGPULayer('bunny', 7);

        const template = {
            x: {
                base: 100,
                amplitude: 600,
                duration: 1000
            },
            scaleX: 0.2,
            scaleY: 0.2
        };

        template.x.ease = 'Linear';
        template.y = 100;
        layer.addMember(template);
        this.add.text(template.x.base, template.y, 'Linear').setDepth(-1);

        template.x.ease = 'Quad.easeInOut';
        template.y = 150;
        layer.addMember(template);
        this.add.text(template.x.base, template.y, 'Quad.easeInOut').setDepth(-1);

        template.x.ease = 'Smoothstep.easeInOut';
        template.y = 200;
        layer.addMember(template);
        this.add.text(template.x.base, template.y, 'Smoothstep.easeInOut').setDepth(-1);

        template.x.ease = 'Quad.easeIn';
        template.y = 300;
        layer.addMember(template);
        this.add.text(template.x.base, template.y, 'Quad.easeIn').setDepth(-1);

        template.x.ease = 'Smoothstep.easeIn';
        template.y = 350;
        layer.addMember(template);
        this.add.text(template.x.base, template.y, 'Smoothstep.easeIn').setDepth(-1);

        template.x.ease = 'Quad.easeOut';
        template.y = 450;
        layer.addMember(template);
        this.add.text(template.x.base, template.y, 'Quad.easeOut').setDepth(-1);

        template.x.ease = 'Smoothstep.easeOut';
        template.y = 500;
        layer.addMember(template);
        this.add.text(template.x.base, template.y, 'Smoothstep.easeOut').setDepth(-1);
    }
}

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

const game = new Phaser.Game(config);

Создание GPU-слоя для спрайтов

Класс SpriteGPULayer — это высокопроизводительный контейнер для отрисовки множества одинаковых спрайтов. Он выносит расчёты на GPU, что идеально для частиц, фоновых элементов или других повторяющихся объектов.

В методе create() создаётся слой, использующий текстуру 'bunny'. Второй аргумент (`7`) задаёт количество спрайтов в слое.

const layer = this.add.spriteGPULayer('bunny', 7);

Шаблон анимации для объектов слоя

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

Свойство `xздесь — не просто число, а объект с параметрами анимации:base(начальная позиция),amplitude(амплитуда движения),duration(длительность в миллисекундах). СвойстваscaleXиscaleY` задают начальный масштаб и не анимируются в данном примере.

const template = {
    x: {
        base: 100,
        amplitude: 600,
        duration: 1000
    },
    scaleX: 0.2,
    scaleY: 0.2
};

Применение разных типов Easing

Easing-функции определяют, как изменяется скорость анимации со временем. Ключевое свойство x.ease задаёт имя функции плавности. После установки ease и координаты `yшаблон добавляется в слой методомlayer.addMember(template)`. Рядом выводится текстовое пояснение.

В примере последовательно применяются семь разных функций. 'Linear' — равномерное движение. 'Quad.easeInOut' — плавное ускорение и замедление. 'Smoothstep' даёт ещё более гладкий переход. Суффиксы .easeIn, .easeOut и .easeInOut указывают, где применяется эффект: в начале, в конце или на всём протяжении анимации.

template.x.ease = 'Linear';
template.y = 100;
layer.addMember(template);
this.add.text(template.x.base, template.y, 'Linear').setDepth(-1);
template.x.ease = 'Quad.easeInOut';
template.y = 150;
layer.addMember(template);
this.add.text(template.x.base, template.y, 'Quad.easeInOut').setDepth(-1);

Как работает добавление членов слоя

Важно понимать, что метод layer.addMember() не копирует сам объект template, а считывает его текущие значения и создаёт на их основе новый спрайт внутри слоя. Поэтому мы можем модифицировать один и тот же объект-шаблон (меняя ease и `y) и снова передавать его вaddMember` — каждый новый спрайт получит актуальные на момент вызова настройки.

Это эффективный паттерн для создания групп объектов со схожей, но вариативной анимацией.

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

Использование SpriteGPULayer с разными easing-функциями — это мощный способ создания сложной анимации множества объектов без ручного управления каждым кадром. Вы можете экспериментировать: анимируйте не только `x, но иy,scale,alphaилиrotation`; комбинируйте несколько анимируемых свойств в одном шаблоне; используйте слои для создания эффектов параллакса или систем частиц с уникальными траекториями.