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

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

Версия 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('block', 'assets/sprites/block.png');
    }

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

        this.matter.add.image(400, 100, 'block', null, { chamfer: 16 }).setBounce(0.9);

        //  These both do the same thing:

        // this.matter.add.pointerConstraint({ length: 1, stiffness: 0.6 });

        this.matter.add.mouseSpring({ length: 1, stiffness: 0.6 });
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#1b1464',
    parent: 'phaser-example',
    physics: {
        default: 'matter'
    },
    scene: Example
};

const game = new Phaser.Game(config);

Настройка проекта и загрузка ассетов

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

class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('block', 'assets/sprites/block.png');
    }

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

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

Затем мы создаем физическое изображение. Функция this.matter.add.image() принимает координаты, ключ текстуры и, что важно, объект с дополнительными свойствами. Параметр { chamfer: 16 } скругляет углы прямоугольного тела, делая его столкновения и отскоки более плавными и естественными. Метод .setBounce(0.9) задает коэффициент упругости (отскока) близкий к 1, что делает объект очень "прыгучим".

create ()
    {
        this.matter.world.setBounds();
        this.matter.add.image(400, 100, 'block', null, { chamfer: 16 }).setBounce(0.9);

Добавление интерактивности: мышиная пружина

Сердце нашего примера — это добавление интерактивности. Phaser с Matter.js предоставляет два очень похожих метода для связывания курсора с физическими телами: pointerConstraint и mouseSpring. В данном примере используется mouseSpring.

Эта функция создает пружинное соединение между указателем мыши (или местом касания) и телом, за которое вы его "схватили". Параметры length и stiffness определяют поведение этой связи. length: 1 задает длину пружины (она будет очень короткой), а stiffness: 0.6 определяет ее жесткость. Чем выше жесткость, тем сильнее пружина стремится вернуться к своей длине, что делает управление более "тугим".

//  Эти две строки делают одно и то же:
        // this.matter.add.pointerConstraint({ length: 1, stiffness: 0.6 });
        this.matter.add.mouseSpring({ length: 1, stiffness: 0.6 });
    }
}

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

Для использования Matter.js необходимо правильно настроить конфигурацию игры. Ключевой момент — указать physics.default как 'matter'. Это активирует физический плагин Matter.js для всей игры. Остальные параметры стандартны: тип рендерера, размеры, цвет фона и родительский контейнер.

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#1b1464',
    parent: 'phaser-example',
    physics: {
        default: 'matter' // Включаем физический движок Matter.js
    },
    scene: Example
};

const game = new Phaser.Game(config);

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

Всего несколько строк кода — и вы добавили в игру реалистичную физику и прямое управление объектами! Matter.js автоматически обрабатывает столкновения, гравитацию и силы пружины. Для экспериментов попробуйте изменить параметры chamfer и bounce у блока, чтобы увидеть, как меняется его поведение. Поиграйте со значениями stiffness и length у mouseSpring, чтобы добиться ощущения "тяжелого" или, наоборот, "невесомого" перетаскивания. Этот механизм можно использовать не только для одного блока, но и для множества интерактивных объектов на сцене.