О чем этот пример
В разработке игр часто возникает необходимость создавать невидимые области, которые реагируют на появление объектов, но не отталкивают их. Например, для триггеров, ловушек или зон подсветки. Пример из официальной документации Phaser демонстрирует, как использовать `Phaser.GameObjects.Zone` совместно с Arcade Physics для обнаружения перекрытия (overlap) с другими телами. Этот подход позволяет отслеживать вход и выход объектов из определенной области, не влияя на их физическое движение, что является мощным инструментом для создания интерактивности в игре.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
zone;
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('block', 'assets/sprites/block.png');
}
create ()
{
this.zone = this.add.zone(300, 200, 200, 200);
// Dynamic body
this.physics.add.existing(this.zone, false);
this.zone.body.moves = false;
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(this.zone, blocks, (zone, block) =>
{
block.setAlpha(0.5);
});
}
update ()
{
this.zone.body.debugBodyColor = this.zone.body.touching.none ? 0x00ffff : 0xffff00;
}
}
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);
Создание и настройка зоны
Первым делом в методе create() создается сама зона (Zone). Это простой игровой объект, представляющий прямоугольную область. Ему задаются координаты и размеры.
Затем ключевой шаг: к зоне добавляется физическое тело с помощью this.physics.add.existing(). Второй параметр false указывает, что тело будет динамическим, но мы сразу отключаем его движение, устанавливая moves = false. Это превращает зону в статический сенсор.
this.zone = this.add.zone(300, 200, 200, 200);
this.physics.add.existing(this.zone, false);
this.zone.body.moves = false;
Группа физических объектов для теста
Чтобы продемонстрировать работу зоны, создается группа (Group) спрайтов 'block' с физикой. Настройки группы задают упругость (bounce) и отскок от границ мира. Несколько блоков создаются в разных точках сцены и получают начальную скорость.
Эти блоки будут свободно летать по сцене под действием гравитации, отскакивая от стен и друг от друга.
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);
// ... и другие блоки
Обработка перекрытия: overlap
Самый важный момент — настройка обработчика события перекрытия (overlap) между зоной и группой блоков. В отличие от столкновения (collide), overlap не приводит к физической реакции (отталкиванию).
Коллбэк-функция вызывается для каждой пары зона-блок, которая в текущем кадре пересекается. В примере при пересечении прозрачность блока устанавливается на 50%.
this.physics.add.overlap(this.zone, blocks, (zone, block) => {
block.setAlpha(0.5);
});
Обратите внимание: так как проверка происходит каждый кадр, блок будет полупрозрачным, только пока находится внутри зоны. Когда он вылетит из нее, его прозрачность останется прежней. Чтобы сбросить альфу, потребуется дополнительная логика.
Визуальная отладка в реальном времени
Включенный режим отладки физики (debug: true в конфиге) позволяет видеть контуры тел. В методе update() каждый кадр меняется цвет отладочной обводки зоны в зависимости от того, касается ли она какого-либо тела.
Свойство body.touching.none будет false, если есть хотя бы одно пересечение. Это наглядный способ визуализировать состояние сенсора прямо в игре.
update ()
{
this.zone.body.debugBodyColor = this.zone.body.touching.none ? 0x00ffff : 0xffff00;
}
Что попробовать дальше
Использование Zone с Arcade Physics — это легкий и эффективный способ создания триггерных областей в вашей игре. Зона работает как невидимый сенсор, фиксирующий факт пересечения с динамическими телами.
Для экспериментов попробуйте
- Изменить коллбэк
overlap, чтобы наносить урон игроку или добавлять очки - Реализовать сброс альфы блока при выходе из зоны, используя событие
worldboundsили отслеживая состояниеtouching - Сделать зону подвижной, задав ей скорость, и наблюдать за реакцией объектов
