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

При разработке игр часто возникает необходимость сохранить состояние объекта или передать его по сети. Метод `toJSON()` для спрайтов и других игровых объектов в Phaser позволяет легко получить их сериализованное представление в формате JSON. Эта статья покажет, как использовать этот метод, что входит в его вывод и почему это полезно для отладки, сохранения прогресса или создания редакторов уровней.

Версия 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 bunny = this.add.sprite(400, 300, 'bunny');

        //  Set a few properties:

        bunny.angle = 25;

        bunny.setScale(1.3);

        bunny.alpha = 0.9;

        bunny.flipY = true;

        console.log(bunny.toJSON());

        // console.log(JSON.stringify(bunny));

    }
}

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

const game = new Phaser.Game(config);

Что делает метод toJSON?

Метод toJSON() — это стандартный JavaScript-метод, который вызывается, когда объект необходимо преобразовать в строку JSON, например, с помощью JSON.stringify(). В Phaser многие классы, включая Phaser.GameObjects.Sprite, переопределяют этот метод, чтобы предоставить удобное для сериализации описание объекта.

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

Разбор примера кода

Рассмотрим исходный код примера. В методе create() создается спрайт bunny, ему задаются некоторые свойства, а затем его состояние выводится в консоль.

const bunny = this.add.sprite(400, 300, 'bunny');

bunny.angle = 25;
bunny.setScale(1.3);
bunny.alpha = 0.9;
bunny.flipY = true;

console.log(bunny.toJSON());

Здесь мы: 1. Создаем спрайт в координатах (400, 300) с текстурой 'bunny'. 2. Устанавливаем угол поворота (angle) в 25 градусов. 3. Задаем масштаб (scale) в 1.3 по обеим осям с помощью setScale. 4. Устанавливаем прозрачность (alpha) в 0.9. 5. Отражаем спрайт по вертикали (flipY = true). 6. Вызываем bunny.toJSON() и выводим результат в консоль.

Структура возвращаемого JSON

Вызов bunny.toJSON() вернет объект примерно следующей структуры. Обратите внимание, что точные названия полей могут зависеть от версии Phaser.

{
    "type": "Sprite",
    "x": 400,
    "y": 300,
    "scaleX": 1.3,
    "scaleY": 1.3,
    "angle": 25,
    "alpha": 0.9,
    "flipX": false,
    "flipY": true,
    "visible": true,
    "texture": "bunny",
    "frame": ""
}

Ключевые поля: - type: Тип игрового объекта (например, 'Sprite'). - `x,y`: Позиция в мире сцены. - scaleX, scaleY: Масштаб по осям. - angle: Угол поворота в градусах. - alpha: Уровень прозрачности (от 0 до 1). - flipX, flipY: Отражается ли спрайт по горизонтали или вертикали. - visible: Видим ли объект. - texture: Ключ загруженной текстуры. - frame: Имя кадра из атласа, если используется (в данном примере пустая строка).

Разница между toJSON() и JSON.stringify()

В примере есть закомментированная строка:

// console.log(JSON.stringify(bunny));

В чем разница? - bunny.toJSON() напрямую вызывает переопределенный метод объекта, который возвращает готовый объект для сериализации. - JSON.stringify(bunny) — это глобальный метод JavaScript. Когда он пытается преобразовать объект bunny, он сначала проверяет, есть ли у этого объекта метод toJSON(). Если метод есть (как в спрайте Phaser), stringify вызывает его и использует возвращенное значение. Таким образом, в данном контексте результат будет идентичным.

Использование toJSON() напрямую может быть полезно, если вам нужен объект, а не строка. Для получения строки JSON удобнее использовать JSON.stringify(bunny).

Практическое применение

Зачем это нужно в реальном проекте?

1. **Отладка**: Быстро проверить состояние объекта в консоли.

console.log('Состояние врага:', enemySprite.toJSON());

2. **Сохранение игры**: Сохранить позиции и состояние ключевых объектов.

const saveData = {
    player: playerSprite.toJSON(),
    checkpoint: flagSprite.toJSON()
};
localStorage.setItem('gameSave', JSON.stringify(saveData));

3. **Создание редактора уровней**: Экспорт расставленных объектов в файл уровня.

Важно помнить, что toJSON() сериализует только основные свойства. Если ваш объект имеет сложные компоненты (например, тело из Arcade Physics), они не будут включены в вывод автоматически. Для их сохранения потребуется дополнительная логика.

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

Метод toJSON() — это мощный и простой инструмент для получения сериализованного состояния игровых объектов в Phaser. Он идеально подходит для отладки, систем сохранения и создания инструментов для разработки. Попробуйте поэкспериментировать: сохраните состояние нескольких объектов в массив, восстановите их из JSON на новой сцене или создайте простой инструмент для клонирования объектов через сериализацию.