О чем этот пример

Работа с физикой — ключевой элемент многих игр. 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('red', 'assets/sprites/columns-red.png');
    }

    create ()
    {
        this.matter.world.setBounds().disableGravity();

        const circ = this.matter.add.image(200, 50, 'red');

        //  Change the body to a Circle with a radius of 48px
        circ.setBody({
            type: 'circle',
            radius: 48
        });

        //  Just make the body move around and bounce
        circ.setVelocity(6, 3);
        circ.setAngularVelocity(0.01);
        circ.setBounce(1);
        circ.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

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

const config = {
    type: Phaser.AUTO,
    physics: {
        default: 'matter', // Активируем Matter.js как физический движок
        matter: {
            debug: true // Включаем отладочную отрисовку тел
        }
    },
    scene: Example
};

Ключевой параметр default: 'matter' подключает плагин. Опция debug: true визуализирует реальные границы физических тел, что незаменимо при отладке. Движок создаст мир (this.matter.world), в котором будут происходить все расчеты.

Создание мира и отключение гравитации

В методе create() сцены мы настраиваем физический мир под наши нужды. В данном примере мы создаем изолированную среду для демонстрации.

create ()
{
    this.matter.world.setBounds().disableGravity();
}

Метод setBounds() автоматически создает статические границы по краям игрового поля, чтобы объекты не улетали за его пределы. Вызов disableGravity() отключает всемирное тяготение внутри мира. Это позволяет объекту двигаться по заданной нами траектории без влияния внешних сил.

Создание спрайта с физическим телом

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

const circ = this.matter.add.image(200, 50, 'red');

Функция this.matter.add.image(x, y, textureKey) делает три вещи: создает графический спрайт с текстурой 'red', создает для него физическое тело по умолчанию (прямоугольник, совпадающий с размером текстуры) и добавляет это тело в симуляцию Matter.js. Объект circ теперь одновременно и спрайт, и физическое тело (Rigid Body).

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

Самая важная часть примера — изменение формы коллайдера. Внешний вид (текстура) остается прежним, но физическое представление меняется на круг.

//  Change the body to a Circle with a radius of 48px
circ.setBody({
    type: 'circle',
    radius: 48
});

Метод setBody(config) заменяет текущее тело объекта. Конфиг с параметрами type: 'circle' и radius: 48 указывает движку создать круглое тело с заданным радиусом в пикселях. Это тело будет корректно сталкиваться и отскакивать, как шар. Отладочная графика (debug: true) наглядно покажет этот синий круг, который может не совпадать с границами спрайта.

Придание движения и свойств

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

circ.setVelocity(6, 3);
circ.setAngularVelocity(0.01);
circ.setBounce(1);
circ.setFriction(0, 0, 0);

* setVelocity(x, y) задает линейную скорость по осям. * setAngularVelocity(value) придает вращение. * setBounce(1) устанавливает коэффициент упругости (реституцию) в 1, что означает идеально упругие столкновения без потер энергии. * setFriction(0, 0, 0) обнуляет трение: статическое, динамическое и воздушное. Объект будет скользить по поверхностям и в воздухе без замедления.

Что попробовать дальше

Использование setBody() в Matter.js дает полный контроль над физическим представлением игровых объектов. Вы можете создавать сложные композитные тела, полигоны и круги, независимо от визуала. Для экспериментов попробуйте изменить radius, задать type: 'rectangle' с разными размерами, добавить гравитацию в мир (enableGravity()) или создать несколько тел разной формы и наблюдать за их столкновениями.