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

Интеграция скелетной анимации Spine открывает для разработчиков игр на Phaser новые горизонты в создании плавных и выразительных персонажей. В этой статье мы разберем практический пример настройки и использования SpinePlugin, который позволяет рендерить сложные анимации, созданные в Spine Editor. Вы узнаете, как правильно конфигурировать сцену для работы с плагином, загружать ресурсы и добавлять анимированных персонажей на игровой холст, а также как сочетать их с обычными спрайтами и графическими примитивами для создания сложных композиций.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super({
            pack: {
                files: [
                    { type: 'scenePlugin', key: 'SpinePlugin', url: 'plugins/3.8.95/SpinePluginDebug.js', sceneKey: 'spine' }
                ]
            }
        });
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('logo', 'assets/sprites/phaser.png');

        this.load.setPath('assets/spine/3.8/demos/');

        this.load.spine('set1', 'demos.json', [ 'atlas1.atlas' ], true);
    }

    create ()
    {
        this.add.image(0, 0, 'logo').setOrigin(0);

        this.add.ellipse(130, 200, 96, 128, 0xffffff);

        // this.add.image(300, 0, 'logo').setOrigin(0);

        this.add.spine(460, 600, 'set1.spineboy', 'idle', true);

        this.add.image(500, 0, 'logo').setOrigin(0);
    }
}

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

const game = new Phaser.Game(config);

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

Для работы с анимациями Spine в Phaser требуется специальный плагин. В отличие от стандартных ассетов, его необходимо зарегистрировать на уровне сцены через параметр pack в конструкторе.

constructor ()
{
    super({
        pack: {
            files: [
                { 
                    type: 'scenePlugin', 
                    key: 'SpinePlugin', 
                    url: 'plugins/3.8.95/SpinePluginDebug.js', 
                    sceneKey: 'spine' 
                }
            ]
        }
    });
}

Этот код сообщает Phaser, что для данной сцены нужно загрузить файл плагина SpinePluginDebug.js и сделать его методы доступными через свойство this.spine. Параметр sceneKey определяет ключ, под которым плагин будет зарегистрирован. После такой конфигурации в сцене автоматически появляется фабрика this.add.spine и загрузчик this.load.spine.

Загрузка ресурсов: изображения и данные Spine

В методе preload происходит подготовка всех необходимых ресурсов. Важно правильно настроить базовые пути, так как ресурсы Spine часто состоят из нескольких файлов.

preload ()
{
    // Устанавливаем общий базовый URL
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('logo', 'assets/sprites/phaser.png');

    // Меняем путь специально для ресурсов Spine
    this.load.setPath('assets/spine/3.8/demos/');

    // Загружаем данные Spine
    this.load.spine('set1', 'demos.json', [ 'atlas1.atlas' ], true);
}

Метод this.load.spine загружает основной JSON-файл скелета (demos.json), файл атласа текстур (atlas1.atlas) и связанные с ним изображения. Последний параметр true указывает, что нужно создать текстуру из загруженного атласа в формате MULTI. Ключ 'set1' будет использоваться для доступа к этому набору данных Spine. Параллельно загружается обычное изображение логотипа Phaser.

Создание объектов на сцене: микс из графики и анимации

Метод create демонстрирует, как совместить обычные игровые объекты Phaser с анимированным персонажем Spine.

create ()
{
    // Стандартный спрайт с логотипом в левом верхнем углу
    this.add.image(0, 0, 'logo').setOrigin(0);

    // Графический примитив - белый эллипс
    this.add.ellipse(130, 200, 96, 128, 0xffffff);

    // Создание персонажа Spine
    this.add.spine(460, 600, 'set1.spineboy', 'idle', true);

    // Еще один спрайт с логотипом
    this.add.image(500, 0, 'logo').setOrigin(0);
}

Ключевая строка — вызов this.add.spine. В ней: - 460, 600 — координаты X и Y для размещения персонажа. - 'set1.spineboy' — ключ ресурса. 'set1' — это имя набора, загруженного ранее, а 'spineboy' — конкретный скин внутри этого набора. - 'idle' — имя анимации, которую нужно проигрывать по умолчанию. - true — флаг, указывающий, что анимацию нужно запустить сразу.

Персонаж Spine становится полноценным игровым объектом, который можно трансформировать и анимировать. Обратите внимание, что закомментированная строка // this.add.image(300, 0, 'logo')... показывает, как можно быстро отключать элементы для отладки композиции.

Структура конфигурации игры

Конфигурация самой игры (config) и ее запуск стандартны для Phaser, что подчеркивает простоту интеграции Spine.

const config = {
    type: Phaser.CANVAS, // Используется рендерер Canvas
    parent: 'phaser-example', // ID DOM-элемента для вставки canvas
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d', // Темно-серый фон
    scene: Example // Главная сцена
};

const game = new Phaser.Game(config);

В этом блоке нет специфичных для Spine параметров. Вся магия происходит внутри сцены, благодаря ранее зарегистрированному плагину. Это позволяет легко добавлять Spine-анимации в существующие проекты.

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

Интеграция Spine в Phaser через официальный плагин — это мощный и при этом достаточно простой процесс. Основные шаги: регистрация плагина в конструкторе сцены, загрузка данных с помощью this.load.spine и создание объекта через this.add.spine. Полученный объект можно анимировать, перемещать и комбинировать с другими элементами игры. Для экспериментов попробуйте: изменить начальную анимацию 'idle' на другую, например 'walk' или 'jump'; настроить глубину отображения (depth) для управления порядком отрисовки относительно других объектов; применить к объекту Spine стандартные трансформации Phaser, такие как setScale или setAlpha; использовать методы самого плагина this.spine для более тонкого контроля над анимациями.