О чем этот пример
В разработке игр часто требуется обмениваться информацией между различными частями игры, например, передавать результаты уровня, состояние игрока или параметры загрузки. В Phaser 3 для этого предусмотрен удобный механизм передачи данных при запуске сцен. Эта статья покажет, как правильно использовать параметры `init`, `create` и метод `scene.start()` для создания модульной и гибкой архитектуры вашей игры.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor()
{
super({ key: 'test', active: false });
}
init (data)
{
this.png = data.image;
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('mech', 'assets/pics/' + this.png);
}
create (data)
{
this.add.image(data.x, data.y, 'mech');
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
game.scene.start('test', { image: 'titan-mech.png', x: 400, y: 300 });
Зачем передавать данные между сценами?
Представьте игру, где главное меню и игровой уровень — это разные сцены. При старте уровня нужно передать сложность, выбранную игроком, или загрузить конкретный набор ресурсов. Жёстко прописывать эти значения в коде сцены — плохая практика. Это делает код негибким и трудным для повторного использования. Механизм передачи данных решает эту проблему, позволяя сцене получать информацию извне.
Анатомия сцены, готовой к приёму данных
Ключевыми точками входа для получения данных в сцене являются методы init() и create(). Оба получают один аргумент — объект data.
class Example extends Phaser.Scene
{
constructor()
{
super({ key: 'test', active: false });
}
init (data)
{
this.png = data.image;
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('mech', 'assets/pics/' + this.png);
}
create (data)
{
this.add.image(data.x, data.y, 'mech');
}
}
Метод init() выполняется до preload(). Здесь удобно сохранить переданные данные в свойства сцены (например, this.png), чтобы использовать их на этапе загрузки. Метод create() получает тот же объект данных, и здесь мы используем его для позиционирования изображения. Разделение логики: init для настройки, create для создания объектов.
Как запустить сцену с данными
Передача данных происходит в момент старта сцены с помощью метода game.scene.start().
const game = new Phaser.Game(config);
game.scene.start('test', { image: 'titan-mech.png', x: 400, y: 300 });
Вторым аргументом мы передаём объект. Его свойства (image, `x,y) будут доступны внутри сцены вinit(data)иcreate(data)какdata.image,data.xиdata.y`. Это прямой и эффективный способ инициализировать сцену с нужными параметрами.
Практические сценарии использования
1. **Динамическая загрузка ресурсов:** Как в примере, вы можете передавать имя файла изображения, чтобы загружать разные спрайты без изменения кода сцены. 2. **Старт уровня с параметрами:** Передайте идентификатор уровня, сложность, здоровье игрока или снаряжение.
game.scene.start('LevelScene', { levelId: 5, difficulty: 'hard', playerHealth: 80 });
3. **Возврат в меню с результатом:** После завершения уровня сцена результатов может получить объект с итоговым счётом и потраченным временем, чтобы отобразить статистику.
Важно помнить: данные, переданные при старте, существуют только для этого конкретного запуска сцены. При рестарте сцены нужно передать их снова.
Что попробовать дальше
Передача данных между сценами — это фундаментальный паттерн в Phaser, который отделяет логику сцены от её контекста запуска. Это делает ваш код чище, а игру — легче в поддержке и расширении. Поэкспериментируйте: создайте сцену-меню, которая собирает настройки игрока, и передавайте их в сцену игры. Или реализуйте систему сохранения, где состояние игры последовательно передаётся от одной сцены к другой.
