Собственные физические тела по вертексам

Phaser предоставляет мощный набор инструментов для работы с физикой через движок Arcade Physics и интеграцию с Matter.js. Возможность создавать кастомные физические тела по вертексам позволяет реализовать сложные формы, выходящие за рамки стандартных прямоугольников или кругов, что важно для точной коллизии и реалистичного поведения объектов в играх.


Настройка проекта с Matter.js

Для использования собственных тел необходим модуль Matter.js, встроенный в Phaser 3:

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    physics: {
        default: 'matter',
        matter: {
            gravity: { y: 1 },
            debug: true
        }
    },
    scene: {
        preload,
        create,
        update
    }
};

const game = new Phaser.Game(config);
  • default: 'matter' — выбор движка физики.
  • gravity задаёт гравитацию по оси Y.
  • debug: true позволяет визуализировать физические тела для удобной отладки.

Определение вертексов для кастомного тела

Matter.js позволяет создавать тела с произвольной формой, передавая массив вертексов. Вертекс представляет собой объект с координатами {x, y} относительно локальной системы координат тела.

let vertices = [
    { x: 0, y: 0 },
    { x: 100, y: 0 },
    { x: 80, y: 50 },
    { x: 0, y: 50 }
];

let polygonBody = this.matter.add.fromVertices(200, 300, vertices, {
    isStatic: false,
    restitution: 0.5,
    friction: 0.1
}, true);
  • fromVertices(x, y, vertices, options, addToWorld) — основной метод для создания тела по массиву вертексов.
  • restitution задаёт упругость при столкновениях.
  • friction определяет коэффициент трения.
  • Последний параметр true автоматически добавляет тело в мир физики.

Использование сложных многоугольников

Для многоугольников с большим количеством вертексов Matter.js применяет алгоритмы триангуляции. Это позволяет разбивать сложную форму на набор треугольников, чтобы физика корректно рассчитывала столкновения.

let complexShape = [
    { x: 0, y: 0 },
    { x: 60, y: -20 },
    { x: 120, y: 0 },
    { x: 100, y: 60 },
    { x: 20, y: 60 }
];

let body = this.matter.add.fromVertices(400, 200, complexShape, {
    isStatic: false,
    restitution: 0.3
}, true);

Matter.js автоматически нормализует вертексы и создаёт физическое тело с корректной коллизией, даже если форма не является выпуклой.


Применение физики к спрайтам

Физическое тело можно привязать к спрайту для визуализации:

let sprite = this.add.sprite(200, 300, 'crate');
this.matter.add.gameObject(sprite, polygonBody);

Важно, чтобы координаты вертексов были локальными для спрайта, иначе столкновения могут работать некорректно. При изменении спрайта или анимации физическое тело автоматически синхронизируется с визуальной частью.


Динамическое изменение формы тела

Matter.js позволяет изменять форму тела на лету, пересоздавая массив вертексов:

function changeShape(body) {
    let newVertices = [
        { x: 0, y: 0 },
        { x: 50, y: -30 },
        { x: 100, y: 0 },
        { x: 80, y: 50 },
        { x: 20, y: 50 }
    ];
    Phaser.Physics.Matter.Matter.Body.setVertices(body, newVertices);
}
  • setVertices(body, vertices) заменяет текущую форму, сохраняя физические свойства.
  • Это полезно для объектов, которые меняют форму при взаимодействии с другими телами или анимациях.

Обработка столкновений кастомных тел

Для работы со столкновениями можно использовать события Matter.js:

this.matter.world.on('collisionstart', function(event) {
    event.pairs.forEach(pair => {
        let bodyA = pair.bodyA;
        let bodyB = pair.bodyB;

        if (bodyA.label === 'player' && bodyB.label === 'obstacle') {
            console.log('Столкновение игрока с препятствием');
        }
    });
});
  • Каждому телу можно присвоить label для идентификации.
  • События collisionstart, collisionend, collisionactive позволяют отслеживать и реагировать на столкновения.

Оптимизация и ограничения

  • Сложные многоугольники могут снижать производительность, особенно при большом количестве объектов.
  • Рекомендуется использовать упрощённые формы или объединять треугольники в составные тела.
  • Вертексы должны быть относительно центра массы для корректного вращения и физики.

Примеры практического применения

  1. Платформеры с нестандартными платформами (трапеции, ломаные линии).
  2. Игровые объекты с разрушаемыми формами, где тело меняется при попадании.
  3. Реалистичные столкновения для транспортных средств или фигур нестандартной формы.

С помощью кастомных тел по вертексам можно создавать игры с физикой, близкой к реальной, сохраняя точность коллизий и гибкость игрового дизайна.