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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        //  Implicit values
        const textConfig = {
            x: 100,
            y: 100,
            text: 'Phaser 3\ntoJSON',
            style: {
                font: '64px Arial',
                fill: '#ffffff',
                align: 'center',
                backgroundColor: '#ff00ff'
            }
        };

        const text = this.make.text(textConfig);

        console.log(text.toJSON());
    }
}

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

const game = new Phaser.Game(config);

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

Каждый игровой объект (Game Object) в Phaser 3 наследуется от базового класса Phaser.GameObjects.GameObject. Этот класс предоставляет метод toJSON(), который сериализует объект в формат JSON. Это означает, что он создает текстовое представление всех ключевых свойств объекта: его тип, координаты, видимость, масштаб, угол поворота и другие важные атрибуты.

Этот JSON можно, например, записать в localStorage, отправить на сервер или вывести в консоль для отладки. Позже, используя этот JSON и фабрику объектов (this.make), вы сможете восстановить объект в точно таком же состоянии.

В нашем примере мы вызываем этот метод для текстового объекта и выводим результат в консоль браузера.

Разбираем пример: создание текстового объекта

Прежде чем вызвать toJSON(), нам нужно создать объект. В примере это делается с помощью фабрики объектов сцены this.make.text(). Фабрика make — это удобный менеджер для создания игровых объектов без необходимости добавлять их на дисплей списка сцены сразу (в отличие от this.add).

Конфигурация объекта передается в виде JavaScript-объекта textConfig. Давайте посмотрим на его структуру:

const textConfig = {
    x: 100,
    y: 100,
    text: 'Phaser 3\ntoJSON',
    style: {
        font: '64px Arial',
        fill: '#ffffff',
        align: 'center',
        backgroundColor: '#ff00ff'
    }
};

* `xиy` — координаты объекта в мире сцены. * text — строка, которая будет отображена. Обратите внимание на использование \n для переноса строки. * style — вложенный объект, определяющий визуальное оформление текста: шрифт, цвет заливки, выравнивание и цвет фона.

После создания конфига мы передаем его в фабрику:

const text = this.make.text(textConfig);

Теперь переменная text содержит экземпляр Phaser.GameObjects.Text.

Сериализация и результат

Самый важный шаг — вызов метода toJSON(). В примере это делается внутри console.log, чтобы мы могли сразу увидеть результат в инструментах разработчика браузера.

console.log(text.toJSON());

Что вы увидите в консоли? Большой JSON-объект, который описывает наш текстовый объект. Вот его ключевые части (структура упрощена для наглядности):

{
    "type": "Text",
    "x": 100,
    "y": 100,
    "text": "Phaser 3\ntoJSON",
    "style": {
        "font": "64px Arial",
        "fill": "#ffffff",
        "align": "center",
        "backgroundColor": "#ff00ff"
    },
    "origin": { "x": 0, "y": 0 },
    "scale": { "x": 1, "y": 1 },
    "visible": true,
    "alpha": 1,
    "angle": 0,
    // ... и многие другие свойства
}

Обратите внимание, что метод возвращает не строку, а уже разобранный JavaScript-объект. Phaser внутренне использует это для своей системы сериализации. Если вам нужна именно строка, можно использовать JSON.stringify(text.toJSON()).

Самое ценное здесь — свойство "type": "Text". Именно по этому типу фабрики Phaser понимают, какой конкретно объект нужно создать при десериализации.

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

Зачем это может понадобиться в реальном проекте?

1. **Сохранение прогресса (чекпоинты)**: Вы можете собрать JSON всех важных объектов на уровне (положение игрока, состояние врагов, собранные предметы) и сохранить эту строку. При загрузке игры — распарсить JSON и восстановить сцену. 2. **Редакторы уровней**: Если вы создаете внутренний инструмент для дизайна уровней, toJSON() — идеальный формат для экспорта расставленных вами объектов в файл данных игры. 3. **Сетевая игра**: Для передачи минимального состояния объекта другому игроку по сети можно отправить компактный JSON. 4. **Отладка**: Быстро залогировать полное состояние сложного объекта, чтобы понять, почему он ведет себя не так, как ожидалось.

Важный нюанс: метод сериализует только данные, специфичные для игрового объекта Phaser. Он не сохранит пользовательские свойства или методы, которые вы добавили в объект самостоятельно. Для этого нужно реализовывать собственную логику сериализации.

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

Метод toJSON() — это встроенный в Phaser 3 инструмент для сериализации, который открывает возможности для сохранения состояния игры, создания инструментов и упрощения отладки. Начните экспериментировать с ним: попробуйте сериализовать не только текст, но и спрайты (Sprite), графику (Graphics) или контейнеры (Container). Задача для практики: создайте простой механизм «сохранить/загрузить», который записывает JSON-строку в localStorage при нажатии клавиши S и воссоздает все объекты сцены при нажатии клавиши L.