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

При создании игр с физикой важно не только управлять скоростью и отскоком объектов, но и учитывать их массу. Этот параметр напрямую влияет на то, как объекты ведут себя при столкновениях, позволяя создавать более реалистичные и интересные взаимодействия. В статье разберем простой пример, демонстрирующий разницу между легким и тяжелым объектом, и покажем, как это работает в движке Arcade Physics.

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

    create ()
    {
        const block = this.physics.add.image(200, 300, 'block');

        block.setBounce(1);

        const ball = this.physics.add.image(0, 300, 'ball');

        ball.setBounce(1);
        ball.setMass(10);
        ball.setVelocityX(100);

        this.physics.add.collider(ball, block);
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    physics: {
        default: 'arcade',
        arcade: { debug: false }
    },
    scene: Example
};

const game = new Phaser.Game(config);

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

Пример начинается с создания класса сцены, унаследованного от Phaser.Scene. В методе preload мы загружаем два спрайта, которые будут использоваться в качестве физических тел. Важно отметить, что здесь используется метод load.setBaseURL для задания базового пути к ресурсам, что упрощает загрузку изображений по относительным путям.

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

Создание физических тел с разными свойствами

В методе create мы создаем два физических тела с помощью this.physics.add.image. Первый объект — статичный блок, второй — мяч, который будет двигаться. Оба тела имеют коэффициент отскока (setBounce), равный 1, что означает идеально упругий удар без потери энергии. Ключевое отличие — мячу с помощью метода setMass задается масса, равная 10, и начальная горизонтальная скорость (setVelocityX). Блок же остается с массой по умолчанию (1).

const block = this.physics.add.image(200, 300, 'block');
block.setBounce(1);

const ball = this.physics.add.image(0, 300, 'ball');
ball.setBounce(1);
ball.setMass(10);
ball.setVelocityX(100);

Добавление коллайдера для обработки столкновений

Чтобы объекты взаимодействовали друг с другом, необходимо добавить коллайдер. В Arcade Physics для этого используется метод this.physics.add.collider. Он автоматически обрабатывает столкновения между указанными телами, применяя законы физики, включая учет массы. В данном случае коллайдер связывает мяч и блок. Из-за большой массы мяча (10 против 1 у блока) при столкновении блок получит значительный импульс и отлетит с большей скоростью, демонстрируя разницу в инерции.

this.physics.add.collider(ball, block);

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

Для запуска примера нужно создать конфигурационный объект игры. В нем указывается тип рендерера, размеры холста, родительский элемент и настройки физики. Здесь используется движок Arcade Physics с отключенным режимом отладки (debug: false). Сцена, которую мы описали, передается в конфиг. Инициализация игры происходит через создание экземпляра Phaser.Game.

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    physics: {
        default: 'arcade',
        arcade: { debug: false }
    },
    scene: Example
};

const game = new Phaser.Game(config);

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

Масса — мощный инструмент для создания разнообразных физических взаимодействий в играх на Phaser. Экспериментируйте с разными значениями setMass для объектов, попробуйте комбинировать массу с другими параметрами, например, с трением (setFriction) или ускорением (setAcceleration). Также можно создать сцену с несколькими объектами разной массы и наблюдать за цепной реакцией столкновений, чтобы глубже понять физическую модель движка.