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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    cursors;
    image;

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

    create ()
    {
        this.image = this.matter.add.image(400, 300, 'block');

        this.matter.add.image(700, 200, 'block').setBounce(0.6);
        this.matter.add.image(100, 500, 'block').setBounce(0.6);

        this.matter.world.setBounds(0, 0, 800, 600);

        this.cursors = this.input.keyboard.createCursorKeys();
    }

    update ()
    {
        if (this.cursors.left.isDown)
        {
            this.image.setVelocityX(-10);
        }
        else if (this.cursors.right.isDown)
        {
            this.image.setVelocityX(10);
        }
        else
        {
            this.image.setVelocityX(0);
        }

        if (this.cursors.up.isDown)
        {
            this.image.setVelocityY(-10);
        }
        else if (this.cursors.down.isDown)
        {
            this.image.setVelocityY(10);
        }
        else
        {
            this.image.setVelocityY(0);
        }
    }
}

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

const game = new Phaser.Game(config);

Настройка сцены и физики Matter

Первым делом необходимо создать конфигурацию игры, указав Matter.js в качестве физического движка. Это ключевой шаг, без которого методы this.matter будут недоступны.

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

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#1b1464',
    parent: 'phaser-example',
    physics: {
        default: 'matter', // Активация плагина Matter.js
        matter: {
            gravity: {
                x: 0, // Горизонтальная гравитация отключена
                y: 0  // Вертикальная гравитация отключена
            }
        }
    },
    scene: Example
};

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

В методе create() сцены происходит инициализация всех игровых объектов. Мы используем фабрику this.matter.add.image для создания спрайтов, которые сразу становятся физическими телами (rigid bodies).

Основное тело, которым будем управлять, сохраняется в свойство класса this.image. Два других блока добавлены как статичные препятствия с высоким коэффициентом упругости (setBounce(0.6)).

Метод this.matter.world.setBounds создает невидимые статические стены по краям игровой области, ограничивая движение всех физических тел.

create ()
{
    // Создаем тело, которым будем управлять
    this.image = this.matter.add.image(400, 300, 'block');

    // Создаем два статических тела-препятствия с отскоком
    this.matter.add.image(700, 200, 'block').setBounce(0.6);
    this.matter.add.image(100, 500, 'block').setBounce(0.6);

    // Устанавливаем границы физического мира (лево, верх, ширина, высота)
    this.matter.world.setBounds(0, 0, 800, 600);

    // Инициализируем слушатель клавиш-стрелок
    this.cursors = this.input.keyboard.createCursorKeys();
}

Обработка ввода и управление скоростью

Логика движения реализована в методе update(), который вызывается на каждом кадре игры. Мы проверяем состояние клавиш-стрелок (isDown) и в зависимости от нажатой кнопки применяем к телу линейную скорость по оси X или Y с помощью метода setVelocityX() / setVelocityY().

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

update ()
{
    // Управление движением по горизонтали
    if (this.cursors.left.isDown)
    {
        this.image.setVelocityX(-10);
    }
    else if (this.cursors.right.isDown)
    {
        this.image.setVelocityX(10);
    }
    else
    {
        this.image.setVelocityX(0); // Остановка, если клавиши не нажаты
    }

    // Управление движением по вертикали
    if (this.cursors.up.isDown)
    {
        this.image.setVelocityY(-10);
    }
    else if (this.cursors.down.isDown)
    {
        this.image.setVelocityY(10);
    }
    else
    {
        this.image.setVelocityY(0); // Остановка, если клавиши не нажаты
    }
}

Ключевые методы Matter.js API

В примере используются несколько основных методов API Matter.js в Phaser:

*   `this.matter.add.image(x, y, texture)` — фабричный метод для создания физического тела на основе изображения. Возвращает объект `MatterImage`.
*   `.setVelocityX(value)` / `.setVelocityY(value)` — установка линейной скорости тела по соответствующей оси. Скорость задается в пикселях в секунду.
*   `.setBounce(value)` — задает коэффициент реституции (упругости) тела. Значение 1 означает абсолютно упругий удар, 0 — абсолютно неупругий.
*   `this.matter.world.setBounds(x, y, width, height)` — создает статические стены, ограничивающие мир. Все динамические тела будут с ними сталкиваться.
*   `this.input.keyboard.createCursorKeys()` — возвращает объект `CursorKeys` для удобного отслеживания состояния стрелок вверх, вниз, влево и вправо.

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

Вы создали базовую систему управления физическим телом с помощью Matter.js. Основной принцип — прямое управление скоростью тела в ответ на ввод пользователя, что дает предсказуемую и отзывчивую механику. **Идеи для экспериментов:** 1. Добавьте гравитацию в конфигурации (y: 0.2) и попробуйте управлять телом в прыжке, используя setVelocityY только при нажатии вверх. 2. Замените прямое присвоение скорости на применение силы с помощью applyForce(). Это создаст более инерционное и "тяжелое" управление. 3. Сделайте управляемого персонажа динамичным телом (как в примере), а платформы — статичными, используя isStatic: true при создании, чтобы создать классический платформер.