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

При разработке игр на Phaser 3 часто возникает необходимость хранить состояние игрока или уровня: количество жизней, очки, текущий этап. Размещать эти данные в глобальных переменных — плохая практика, которая ведёт к путанице. В этой статье мы разберём встроенный и элегантный способ — использование плагина Scene Data, доступного через `this.data`. Этот метод позволяет хранить информацию непосредственно в контексте сцены, делая код чище, а данные — защищёнными от случайного вмешательства.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
    }

    create ()
    {
        //  Using the Scene Data Plugin we can store data on a Scene level
        this.data.set('lives', 3);
        this.data.set('level', 5);
        this.data.set('score', 2000);

        var text = this.add.text(100, 100, '', { font: '64px Courier', fill: '#00ff00' });

        text.setText([
            'Level: ' + this.data.get('level'),
            'Lives: ' + this.data.get('lives'),
            'Score: ' + this.data.get('score')
        ]);
    }
}

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

const game = new Phaser.Game(config);

Что такое `this.data`?

Каждая сцена в Phaser 3 имеет встроенный менеджер данных — плагин Scene Data (this.data). Это простое хранилище «ключ-значение», привязанное к жизненному циклу сцены. Когда сцена запускается, хранилище создаётся, а когда сцена завершает работу (например, через scene.stop()), данные автоматически очищаются. Это делает его идеальным для временных данных уровня.

Основные методы, которые мы будем использовать — set() для записи и get() для чтения.

Запись данных в хранилище сцены

Инициализировать данные лучше всего в методах init() или create(). Метод set() принимает два аргумента: ключ (строка) и значение (любой тип данных: число, строка, объект и т.д.).

this.data.set('lives', 3);
this.data.set('level', 5);
this.data.set('score', 2000);

В этом примере мы сохраняем три числовых значения под ключами 'lives', 'level' и 'score'. Эти данные теперь доступны в любой функции внутри этой сцены через объект this.data.

Чтение данных и их использование

Чтобы получить сохранённое значение, используется метод get(), куда передаётся ключ. Полученные данные можно сразу использовать в логике игры или, как в нашем примере, для отображения в интерфейсе.

var text = this.add.text(100, 100, '', { font: '64px Courier', fill: '#00ff00' });

text.setText([
    'Level: ' + this.data.get('level'),
    'Lives: ' + this.data.get('lives'),
    'Score: ' + this.data.get('score')
]);

Здесь мы создаём текстовый объект и устанавливаем его содержимое, подставляя значения из хранилища. Обратите внимание: если ключ не существует, get() вернёт undefined.

Почему это лучше глобальных переменных?

Использование this.data вместо глобальных переменных даёт несколько преимуществ: 1. **Инкапсуляция:** Данные изолированы в рамках сцены. Другая сцена не сможет случайно их изменить, если явно не получит к ним доступ. 2. **Автоматическое управление памятью:** Данные очищаются вместе со сценой, что помогает избежать утечек памяти. 3. **Читаемость кода:** Понятно, что переменные lives или score относятся к состоянию именно этой сцены, а не являются глобальными настройками игры. 4. **Реактивность (опционально):** У плагина есть события (например, changedata), которые позволяют реагировать на изменение значений, что полезно для обновления UI.

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

Плагин Scene Data — это простой и мощный инструмент для управления состоянием сцены в Phaser 3. Он помогает писать чистый и поддерживаемый код. Для экспериментов попробуйте

  1. Сохранить в this.data сложный объект с настройками игрока
  2. Изменить значение (например, уменьшить lives при столкновении) и автоматически обновить текст на экране, подписавшись на событие changedata
  3. Использовать this.data.values для получения всех сохранённых данных в виде объекта