О чем этот пример
В играх часто требуется реагировать, когда игрок или объект входит в определенную область. Например, для активации ловушки, триггера диалога или зоны повышенной гравитации. Phaser Physics позволяет легко создавать такие невидимые зоны и отслеживать пересечения с другими физическими телами. В этой статье мы разберем пример, где используется `Phaser.Physics.Arcade.StaticBody` для зоны и метод `overlap` для обнаружения в ней динамических тел. Вы научитесь создавать невидимые триггерные области и реагировать на события пересечения в реальном времени.
Версия 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('block', 'assets/sprites/block.png');
}
create ()
{
const zone = this.add.zone(300, 200, 200, 200);
// Static body
this.physics.add.existing(zone, true);
const blocks = this.physics.add.group({
defaultKey: 'block',
bounceX: 1,
bounceY: 1,
collideWorldBounds: true
});
blocks.create(100, 200).setVelocity(100, 200);
blocks.create(500, 200).setVelocity(-100, -100);
blocks.create(300, 400).setVelocity(60, 100);
blocks.create(600, 300).setVelocity(-30, -50);
this.physics.add.overlap(zone, blocks, (_zone, block) =>
{
block.setAlpha(0.5);
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
debug: true,
gravity: { y: 200 }
}
},
scene: Example
};
const game = new Phaser.Game(config);
Создание зоны и превращение её в статическое тело
В Phaser Phaser.GameObjects.Zone — это невидимый прямоугольный объект, предназначенный для обработки событий и логики. Но чтобы использовать его в физических расчетах, например, для обнаружения столкновений или пересечений, ему необходимо добавить физическое тело.
const zone = this.add.zone(300, 200, 200, 200);
this.physics.add.existing(zone, true);
Первой строкой мы создаем зону с центром в точке (300, 200) и размерами 200x200 пикселей. Вторая строка — ключевая. Метод this.physics.add.existing() добавляет к уже существующему игровому объекту тело Arcade Physics. Второй аргумент true указывает, что тело должно быть **статическим** (static: true). Статическое тело не подвержено влиянию сил (гравитации, толчков) и не двигается при столкновениях, что идеально подходит для триггерной зоны.
Создание группы динамических тел
Для демонстрации работы зоны нам нужны движущиеся объекты, пересечение с которыми мы будем отслеживать. Удобнее всего создать для этого физическую группу.
const blocks = this.physics.add.group({
defaultKey: 'block',
bounceX: 1,
bounceY: 1,
collideWorldBounds: true
});
blocks.create(100, 200).setVelocity(100, 200);
blocks.create(500, 200).setVelocity(-100, -100);
// ... другие блоки
Здесь создается группа blocks. Параметр defaultKey указывает текстуру ('block'), которая будет использоваться для всех создаваемых в группе спрайтов. bounceX и bounceY задают коэффициент упругости (1 — идеальный отскок). collideWorldBounds включает столкновение с границами мира.
Метод blocks.create() создает в группе отдельный спрайт с физическим телом в указанных координатах. Метод setVelocity() сразу задает ему начальную скорость, заставляя двигаться.
Отслеживание пересечений с помощью метода overlap
Ядро логики примера — метод this.physics.add.overlap(), который проверяет пересечение двух объектов или групп и запускает callback-функцию при каждом обнаруженном факте пересечения.
this.physics.add.overlap(zone, blocks, (_zone, block) =>
{
block.setAlpha(0.5);
});
Первые два аргумента — это объекты для проверки: наша зона (zone) и группа блоков (blocks). Phaser будет автоматически проверять пересечение зоны с каждым телом из группы.
Третий аргумент — функция-обработчик. Она вызывается **каждый раз**, когда происходит пересечение. В параметры _zone и block автоматически передаются конкретные объекты, которые пересеклись (в нашем случае это всегда наша зона и один из блоков). Внутри обработчика мы изменяем прозрачность блока, попавшего в зону, с помощью block.setAlpha(0.5).
Важные детали работы overlap и отладка
Важно понимать, что overlap — это **процесс**, а не событие. Проверка происходит на каждом игровом кадре, и callback будет вызываться постоянно, пока объекты пересекаются.
physics: {
default: 'arcade',
arcade: {
debug: true,
gravity: { y: 200 }
}
}
Конфигурация физики в этом примере включает два важных момента. Во-первых, gravity: { y: 200 } добавляет постоянное ускорение вниз, заставляя блоки падать и отскакивать, что создает динамичную картину пересечений. Во-вторых, debug: true включает отладочную отрисовку. Вы увидите, что зона обведена зеленой рамкой (признак статического тела), а у блоков будут видны их физические границы (тела). Это невероятно полезно для визуальной настройки.
Что попробовать дальше
Комбинация Zone, StaticBody и overlap предоставляет мощный и производительный инструмент для создания триггерных областей в вашей игре. Вы можете реагировать на вход и выход объекта, менять его состояние или активировать игровые события.
**Идеи для экспериментов:**
1. Измените логику в callback-функции, чтобы блок становился полупрозрачным только при **первом** входе в зону, а при выходе возвращал прозрачность. Для этого вам понадобится отслеживать состояние каждого блока.
2. Сделайте зону не статической, а динамической телом (this.physics.add.existing(zone, false)) и посмотрите, как она будет реагировать на столкновения с блоками.
3. Используйте collider вместо overlap, чтобы блоки не могли проходить сквозь зону, а отталкивались от её границ.
