О чем этот пример
Движок физики Arcade в Phaser 3 предлагает простой и мощный способ реализовать столкновения между игровыми объектами. В этой статье мы разберем, как использовать статическую группу объектов и `collider`, чтобы создать сложные взаимодействия с минимумом кода. Этот подход полезен для создания стен, препятствий, платформ или любого окружения, которое должно реагировать на движение главного героя или других динамических тел.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
group;
sprite;
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('mushroom', 'assets/sprites/mushroom2.png');
this.load.image('ball', 'assets/sprites/shinyball.png');
}
create ()
{
this.sprite = this.physics.add.image(400, 300, 'mushroom');
this.group = this.physics.add.staticGroup({
key: 'ball',
frameQuantity: 30
});
Phaser.Actions.PlaceOnRectangle(this.group.getChildren(), new Phaser.Geom.Rectangle(84, 84, 616, 416));
// We need to call this because placeOnRectangle has changed the coordinates of all the children
// If we don't call it, the static physics bodies won't be updated to reflect them
this.group.refresh();
this.sprite.setVelocity(100, 200).setBounce(1, 1).setCollideWorldBounds(true).setGravityY(200);
this.physics.add.collider(this.sprite, this.group);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
debug: true
}
},
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и загрузка ассетов
Как и в любой сцене Phaser, мы начинаем с методов preload и create. В preload загружаются изображения для наших спрайтов. Важно использовать setBaseURL, чтобы указать базовый путь для загрузки, что упрощает работу с внешними ресурсами.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('mushroom', 'assets/sprites/mushroom2.png');
this.load.image('ball', 'assets/sprites/shinyball.png');
}
В методе create происходит основная настройка физического мира и создание объектов. Обратите внимание, что конфигурация физики arcade с debug: true включена на уровне игры, что позволяет видеть хитбоксы объектов во время отладки.
Создание динамического и статических тел
В Arcade физике есть два основных типа тел: динамические (подвижные) и статические (неподвижные). В нашем примере гриб (mushroom) — это динамическое тело, которое будет двигаться и сталкиваться. Он создается с помощью this.physics.add.image, что сразу добавляет ему физическое тело.
this.sprite = this.physics.add.image(400, 300, 'mushroom');
Статическая группа (staticGroup) создается для шариков (ball). Параметр frameQuantity задает количество создаваемых объектов. Статические тела не двигаются под действием физики, но могут участвовать в столкновениях.
this.group = this.physics.add.staticGroup({
key: 'ball',
frameQuantity: 30
});
Расстановка объектов и обновление физики
После создания группы шариков, мы используем Phaser.Actions.PlaceOnRectangle, чтобы расположить их по периметру прямоугольника. Это удобный метод для геометрического размещения.
Phaser.Actions.PlaceOnRectangle(this.group.getChildren(), new Phaser.Geom.Rectangle(84, 84, 616, 416));
Ключевой момент: после изменения координат объектов в статической группе **необходимо вызвать** refresh(). Этот метод обновляет позиции физических тел в группе. Без этого вызова столкновения будут рассчитываться для старых, неактуальных координат.
this.group.refresh();
Настройка движения и создание коллайдера
Динамическому спрайту гриба задаются начальные физические свойства: скорость (setVelocity), упругость (setBounce), столкновение с границами мира (setCollideWorldBounds) и гравитация (setGravityY).
this.sprite.setVelocity(100, 200).setBounce(1, 1).setCollideWorldBounds(true).setGravityY(200);
Сердцевина примера — создание коллайдера с помощью this.physics.add.collider. Эта функция автоматически обрабатывает столкновения и отскоки между динамическим спрайтом и каждым объектом в статической группе.
this.physics.add.collider(this.sprite, this.group);
Что попробовать дальше
Использование staticGroup и collider — это эффективный способ добавить в игру сложные взаимодействия с окружением. Для экспериментов попробуйте: изменить форму размещения объектов (например, на круг с PlaceOnCircle), добавить больше динамических тел в коллайдер или заменить статическую группу на динамическую, чтобы шарики тоже начали двигаться при столкновениях.
