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

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

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        this.matter.world.setBounds();

        //  Let's create a bunch of random shaped objects and add them to the world

        for (let i = 0; i < 48; i++)
        {
            const x = Phaser.Math.Between(100, 700);
            const y = Phaser.Math.Between(100, 500);

            if (Math.random() < 0.7)
            {
                const sides = Phaser.Math.Between(3, 14);
                const radius = Phaser.Math.Between(8, 50);

                this.matter.add.polygon(x, y, sides, radius, { restitution: 0.9 });
            }
            else
            {
                const width = Phaser.Math.Between(16, 128);
                const height = Phaser.Math.Between(8, 64);

                this.matter.add.rectangle(x, y, width, height, { restitution: 0.9 });
            }
        }

        this.matter.add.mouseSpring();
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#000000',
    parent: 'phaser-example',
    physics: {
        default: 'matter',
        matter: {
            gravity: {
                y: 0
            },
            enableSleep: true,
            debug: true
        }
    },
    scene: Example
};

const game = new Phaser.Game(config);

Настройка сцены и мира

Вся физическая симуляция происходит внутри сцены (Scene). Ключевой шаг — правильная настройка мира (world) в методе create(). Сначала мы устанавливаем границы, чтобы тела не улетали за пределы области просмотра.

this.matter.world.setBounds();

Затем мы создаём цикл для генерации 48 случайных объектов. Их позиция определяется в пределах заданных координат по осям X и Y.

for (let i = 0; i < 48; i++)
{
    const x = Phaser.Math.Between(100, 700);
    const y = Phaser.Math.Between(100, 500);
    // ... генерация тела
}

Генерация случайных многоугольников

С вероятностью 70% в мире будет создан многоугольник (полигон). Phaser.Math.Between используется для задания случайного количества сторон (от 3 до 14) и радиуса (от 8 до 50 пикселей).

if (Math.random() < 0.7)
{
    const sides = Phaser.Math.Between(3, 14);
    const radius = Phaser.Math.Between(8, 50);
    this.matter.add.polygon(x, y, sides, radius, { restitution: 0.9 });
}

Метод this.matter.add.polygon создаёт физическое тело в форме правильного многоугольника. Параметр restitution: 0.9 задаёт высокий коэффициент упругости (отскока), делая столкновения объектов очень «прыгучими».

Создание прямоугольных тел

С вероятностью 30% вместо многоугольника будет создан прямоугольник. Его ширина и высота также выбираются случайным образом.

else
{
    const width = Phaser.Math.Between(16, 128);
    const height = Phaser.Math.Between(8, 64);
    this.matter.add.rectangle(x, y, width, height, { restitution: 0.9 });
}

Метод this.matter.add.rectangle работает аналогично, создавая тело в форме прямоугольника с заданными размерами. Одинаковый параметр упругости (restitution) обеспечивает единообразие физического поведения для всех типов тел.

Интерактивность: пружина для мыши

Чтобы можно было взаимодействовать с созданным миром, в конце метода create() добавляется мышиная пружина.

this.matter.add.mouseSpring();

Этот вызов создаёт специальное соединение между указателем мыши и телами в мире. Зажав левую кнопку мыши на любом объекте, вы сможете его тянуть, толкать и бросать, наблюдая за реалистичной физической реакцией и столкновениями с другими телами.

Конфигурация игры и физики

Вся магия начинается с конфигурационного объекта игры. Здесь критически важна секция physics.

physics: {
    default: 'matter', // Активация Matter.js
    matter: {
        gravity: { y: 0 }, // Отключаем гравитацию по оси Y
        enableSleep: true, // Тела могут "засыпать"
        debug: true        // Включаем отладочную визуализацию
    }
}

gravity: { y: 0 } отключает гравитацию, поэтому тела не падают вниз, а остаются на месте или движутся только от столкновений. enableSleep: true оптимизирует производительность, "усыпляя" неподвижные тела. debug: true рисует контуры всех тел, что незаменимо при разработке.

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

Вы освоили базовый принцип наполнения физического мира в Phaser случайными телами с помощью Matter.js. Это основа для тысяч механик: от башен из блоков до аркадного пинбола. Для экспериментов попробуйте изменить gravity, чтобы тела падали; добавьте разные типы тел (круги, трапеции); поиграйтесь с параметрами вроде friction (трение) или density (плотность), чтобы получить уникальное "чувство" физики вашей игры.