О чем этот пример
Часто в игре нужна физика только на определённых уровнях или сценах, а на других она должна быть отключена. В Phaser 3 есть гибкий подход к конфигурации физического движка Arcade — его можно активировать не для всей игры, а для конкретной сцены. Это позволяет сэкономить ресурсы и сделать логику игры чище. В статье разберем пример, где физика с гравитацией включается только для сцены `OuterSpace`. Мы увидим, как это делается в конструкторе сцены, и как затем использовать `this.physics` для создания физических тел.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Boot extends Phaser.Scene
{
constructor ()
{
super({ key: 'boot' });
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('sky', 'assets/skies/space2.png');
this.load.image('logo', 'assets/sprites/phaser3-logo.png');
this.load.image('red', 'assets/particles/red.png');
}
create ()
{
this.scene.start('outerSpace');
}
}
class OuterSpace extends Phaser.Scene
{
constructor ()
{
super({
key: 'outerSpace',
physics: {
arcade: {
gravity: { y: 200 }
}
}
});
}
create ()
{
this.add.image(400, 300, 'sky');
const particles = this.add.particles(0, 0, 'red', {
speed: 100,
scale: { start: 1, end: 0 },
blendMode: 'ADD'
});
const logo = this.physics.add.image(400, 100, 'logo')
.setVelocity(100, 200)
.setBounce(1, 1)
.setCollideWorldBounds(true);
particles.startFollow(logo);
}
}
const gameConfig = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
scene: [ Boot, OuterSpace ]
};
const game = new Phaser.Game(gameConfig);
Загрузка ресурсов в сцене-загрузчике
Первая сцена Boot отвечает за предварительную загрузку графических ресурсов. Это классический паттерн в Phaser для разделения этапов загрузки и основного геймплея.
В методе preload мы задаем базовый URL для загрузчиков и указываем, какие изображения нужны. После завершения загрузки в методе create происходит запуск следующей сцены.
class Boot extends Phaser.Scene
{
constructor ()
{
super({ key: 'boot' });
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('sky', 'assets/skies/space2.png');
this.load.image('logo', 'assets/sprites/phaser3-logo.png');
this.load.image('red', 'assets/particles/red.png');
}
create ()
{
this.scene.start('outerSpace');
}
}
Локальная конфигурация Arcade Physics
Ключевой момент — настройка физики в конструкторе сцены OuterSpace. Вместо того чтобы активировать Arcade Physics глобально в конфиге игры, мы передаем конфигурацию движка вторым параметром в super().
Это позволяет задать гравитацию только для этой конкретной сцены. В данном случае установлена гравитация по оси Y, равная 200 пикселям в секунду.
class OuterSpace extends Phaser.Scene
{
constructor ()
{
super({
key: 'outerSpace',
physics: {
arcade: {
gravity: { y: 200 }
}
}
});
}
Создание мира и физических тел
В методе create сцены OuterSpace мы видим, как работает настроенная физика. Сначала добавляется фоновое изображение обычным способом через this.add.image.
Затем создается система частиц (this.add.particles), которая будет следовать за логотипом. Это декоративный элемент, не связанный с физикой.
Самое важное — создание физического спрайта. Для этого используется не this.add.image, а this.physics.add.image. Поскольку физика для сцены активирована, этот метод доступен. Созданному логотипу сразу задается начальная скорость, упругость (setBounce) и включение столкновений с границами мира.
create ()
{
this.add.image(400, 300, 'sky');
const particles = this.add.particles(0, 0, 'red', {
speed: 100,
scale: { start: 1, end: 0 },
blendMode: 'ADD'
});
const logo = this.physics.add.image(400, 100, 'logo')
.setVelocity(100, 200)
.setBounce(1, 1)
.setCollideWorldBounds(true);
particles.startFollow(logo);
}
}
Итоговая конфигурация игры
В глобальной конфигурации игры scene указывается просто массив классов сцен. Обратите внимание, что здесь нет свойства physics. Вся необходимая конфигурация физического движка уже содержится внутри класса OuterSpace. При такой архитектуре сцена Boot будет работать без физики, что и требовалось.
const gameConfig = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
scene: [ Boot, OuterSpace ]
};
const game = new Phaser.Game(gameConfig);
Что попробовать дальше
Использование локальной конфигурации Arcade Physics на уровне сцены — мощный инструмент для оптимизации и организации кода. Он позволяет включать физику только там, где она действительно нужна, избегая лишних вычислений в меню, загрузочных экранах или кат-сценах.
Для экспериментов попробуйте: создать сцену с другой силой гравитации или без нее; добавить в сцену Boot статический спрайт и убедиться, что методы this.physics в ней недоступны; использовать в одной игре несколько физических движков (например, Arcade на одной сцене и Matter.js на другой), настраивая их аналогичным образом.
