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

При работе с физикой в 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('blue', 'assets/sprites/columns-blue.png');
    }

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

        //  By default it will create a rectangular body the size of the texture
        const rect = this.matter.add.image(200, 50, 'blue');

        //  However, you can tell it to create any size rectangle you like, such as this one:
        rect.setBody({
            type: 'rectangle',
            width: 128,
            height: 128
        });

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

Настройка сцены и загрузка ассетов

Всё начинается с базовой настройки сцены. В методе preload мы указываем базовый URL для загрузки ресурсов и загружаем одно изображение — синюю колонну.

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

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);

Подготовка мира и создание тела по умолчанию

В методе create мы сначала подготавливаем физический мир. this.matter.world.setBounds() создаёт границы по краям игрового поля, чтобы тело не улетело за его пределы. disableGravity() отключает глобальную гравитацию, что позволит телу двигаться по заданной нами траектории без падения.

Затем мы создаём первое физическое тело. Метод this.matter.add.image создаёт игровой объект (Image), который сразу же наделяется физическим телом Matter. По умолчанию размер этого тела (коллайдера) точно соответствует размеру загруженной текстуры 'blue'.

create ()
{
    this.matter.world.setBounds().disableGravity();
    const rect = this.matter.add.image(200, 50, 'blue');
}

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

Часто размер спрайта не совпадает с желаемыми границами столкновений. Phaser позволяет легко это исправить. Метод setBody() объекта, созданного через matter.add.image, заменяет текущее физическое тело на новое с заданными параметрами.

В примере мы указываем type: 'rectangle' и задаём конкретные width и height. Важно понимать: меняется только физическое тело (хитбокс). Визуальный спрайт остаётся прежнего размера. Это хорошо видно при включённом debug: true.

rect.setBody({
    type: 'rectangle',
    width: 128,
    height: 128
});

Задание движения и физических свойств

Чтобы тело двигалось и взаимодействовало с миром, нужно задать его динамические свойства. В примере мы применяем несколько методов: - setVelocity() задаёт линейную скорость по осям X и Y. - setAngularVelocity() задаёт скорость вращения тела. - setBounce() определяет упругость (коэффициент восстановления). Значение 1 означает абсолютно упругое столкновение без потерь энергии. - setFriction() настраивает трение. Параметры (0, 0, 0) означают отсутствие трения о воздух, поверхности и статическое трение соответственно.

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

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

Использование setBody() для определения пользовательских прямоугольных тел — это мощный инструмент для точного контроля над физикой в Matter.js. Вы можете создавать хитбоксы, которые меньше или больше спрайта, что полезно для создания областей взаимодействия, упрощённых коллайдеров для сложных форм или trigger-зон. Для экспериментов попробуйте: создать несколько тел разных размеров и наблюдать за их столкновениями; изменить параметры setBounce и setFriction, чтобы получить разное поведение при соударениях; или использовать этот подход как первый шаг к созданию составных тел из нескольких прямоугольников.