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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    ball;

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

    create ()
    {
        this.ball = this.matter.add.image(50, 0, 'ball');

        this.ball.setCircle();
        this.ball.setFriction(0.005);
        this.ball.setBounce(0.6);
        this.ball.setVelocityX(1);
        this.ball.setAngularVelocity(0.15);

        const ground = this.matter.add.image(400, 400, 'platform');

        ground.setStatic(true);
        ground.setScale(2, 0.5);
        ground.setAngle(10);
        ground.setFriction(0.005);
    }

    update ()
    {
        if (this.ball.y > 600)
        {
            this.ball.setPosition(50, 0);
            this.ball.setVelocity(0, 0);
        }
    }
}

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

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

Вся логика примера содержится в классе сцены Example. В методе preload мы загружаем два изображения: спрайт мяча ('ball') и спрайт платформы ('platform'). Обратите внимание на использование setBaseURL — это удобный способ указать базовый путь для всех загружаемых ресурсов.

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

Создание и настройка динамического тела (мяча)

В методе create мы создаем первое физическое тело — мяч. Ключевой метод здесь — this.matter.add.image. Он создает игровой объект Image, к которому сразу прикреплен компонент тела Matter.js.

После создания мы настраиваем его физические свойства с помощью методов, предоставляемых Matter.js. Самый важный из них — setCircle(). По умолчанию тело имеет прямоугольную форму (AABB), соответствующую размерам текстуры. setCircle() заменяет эту форму на точный круг, что критически важно для реалистичного качения.

Остальные методы задают параметры движения и взаимодействия.

this.ball = this.matter.add.image(50, 0, 'ball');

this.ball.setCircle();
this.ball.setFriction(0.005); // Низкое трение о поверхность
this.ball.setBounce(0.6);     // Коэффициент упругости (отскок)
this.ball.setVelocityX(1);    // Начальная горизонтальная скорость
this.ball.setAngularVelocity(0.15); // Начальная скорость вращения

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

Второе тело — это земля или платформа. Мы создаем его тем же методом this.matter.add.image. Однако, в отличие от мяча, это тело должно быть неподвижным. Для этого используется метод setStatic(true).

Статичное тело не подвержено силам гравитации и импульсам от столкновений, но может сталкиваться с другими телами. Мы также меняем его масштаб с помощью setScale и задаем небольшой угол наклона с помощью setAngle, чтобы мяч мог скатываться.

const ground = this.matter.add.image(400, 400, 'platform');

ground.setStatic(true);
ground.setScale(2, 0.5);
ground.setAngle(10);
ground.setFriction(0.005);

Базовая игровая логика и конфигурация

В методе update реализован простой респаун мяча: если он упадет ниже отметки y > 600, его позиция и скорость сбрасываются в исходное состояние.

Конфигурация игры (config) — это сердце приложения Phaser. Здесь мы указываем, что в качестве физического движка по умолчанию должен использоваться 'matter'. Это обязательный шаг для работы кода из примера.

update ()
{
    if (this.ball.y > 600)
    {
        this.ball.setPosition(50, 0);
        this.ball.setVelocity(0, 0);
    }
}
const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#1b1464',
    parent: 'phaser-example',
    physics: { // Включение Matter.js
        default: 'matter'
    },
    scene: Example
};

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

Теперь у вас есть рабочая сцена с двумя физическими телами, обладающими разными свойствами. Для экспериментов попробуйте изменить параметры: увеличьте setBounce мяча до 1.0 для супер-прыгучего мяча, сделайте платформу динамической (setStatic(false)) или добавьте несколько мячей с разными скоростями вращения (setAngularVelocity). Это основа для создания сложных физических взаимодействий.