О чем этот пример
При создании игр с физикой форма коллайдера объекта — краеугольный камень реалистичного поведения. Часто спрайт имеет сложную форму, которую прямоугольный или круглый хитбокс описывает плохо. Phaser в связке с движком Matter.js позволяет легко создавать полигональные (многоугольные) тела, не зависящие от текстуры спрайта. Это открывает путь к точным и визуально приятным столкновениям для объектов любой формы — от шестиугольных гаек до неправильных астероидов.
Версия 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('orange', 'assets/sprites/columns-orange.png');
}
create ()
{
this.matter.world.setBounds().disableGravity();
const poly = this.matter.add.image(200, 50, 'orange');
poly.setBody({
type: 'polygon',
sides: 6,
radius: 64
});
// Just make the body move around and bounce
poly.setVelocity(6, 3);
poly.setAngularVelocity(0.01);
poly.setBounce(1);
poly.setFriction(0, 0, 0);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#1b1464',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
debug: true
}
},
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и физики
Вся работа начинается с корректной настройки физического движка Matter.js в конфигурации игры. Ключевой параметр debug: true включает отладочную отрисовку, которая будет визуализировать создаваемые нами полигональные тела.
const config = {
type: Phaser.AUTO,
physics: {
default: 'matter',
matter: {
debug: true // Включаем отладочную отрисовку тел
}
},
scene: Example
};
В методе create() сцены мы подготавливаем мир. Вызов setBounds() автоматически создает статические стены по границам мира, а disableGravity() отключает гравитацию, чтобы наше тело двигалось по заданной нами траектории.
create ()
{
this.matter.world.setBounds().disableGravity();
// ... Дальнейший код создания тела
}
Создание спрайта с физическим телом
Изначально физическое тело создается на основе прямоугольного контура (баундинг бокса) изображения. Мы создаем физический спрайт с помощью this.matter.add.image. На этом этапе тело спрайта — это прямоугольник размером с текстуру 'orange'.
const poly = this.matter.add.image(200, 50, 'orange');
Важно понимать, что теперь poly — это не просто изображение, а комплексный объект, содержащий и спрайт для отрисовки, и физическое тело (body) для расчетов столкновений и движения.
Переопределение формы тела на полигональную
Вот где происходит магия. Метод setBody() позволяет полностью заменить форму физического тела объекта. Мы передаем в него объект конфигурации, описывающий нужную нам геометрию.
poly.setBody({
type: 'polygon', // Указываем тип тела — многоугольник
sides: 6, // Количество сторон
radius: 64 // Радиус описанной окружности
});
После этого вызова физическое тело poly становится правильным шестиугольником с радиусом 64 пикселя. Обратите внимание: спрайт с изображением апельсиновой колонны продолжает отрисовываться, но столкновения теперь рассчитываются по невидимому шестиугольнику, который мы видим благодаря включенному дебаг-режиму (зеленый контур). Это мощный прием для создания точной физики у объектов со сложными визуальными формами.
Задание движения и физических свойств
Когда тело создано, мы можем управлять его динамикой. В примере задается начальная скорость, вращение, упругость и трение. Эти свойства применяются уже к новому полигональному телу.
// Задаем линейную скорость по осям X и Y
poly.setVelocity(6, 3);
// Задаем угловую скорость (вращение)
poly.setAngularVelocity(0.01);
// Устанавливаем коэффициент упругости (1 = идеальный отскок)
poly.setBounce(1);
// Отключаем трение: первое число — линейное, остальные — угловое и воздушное
poly.setFriction(0, 0, 0);
Благодаря setBounce(1) и отключенному трению тело будет бесконечно двигаться и отскакивать от границ мира (setBounds) без потери энергии, демонстрируя идеальную физику.
Что попробовать дальше
Метод setBody() в Matter.js — это ключ к созданию точной и производительной физики для объектов сложной формы. Вы больше не привязаны к прямоугольнику текстуры. Для экспериментов попробуйте: изменить число sides на 3 (треугольник) или 8 (восьмиугольник); использовать type: 'circle' или type: 'trapezoid'; привязать полигональное тело к анимированному спрайту; создать составное тело из нескольких простых фигур с помощью type: 'compound'.
