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

При создании игр с физикой важно понимать, как взаимодействуют объекты. Параметр `mass` (масса) в Phaser 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 ()
    {
        // var blocks = this.physics.add.group({
        //     key: 'block',
        //     frameQuantity: 1,
        //     setXY: { x: 200, y: 100, stepY: 100 }
        // });

        // var ball1 = this.physics.add.image(0, 100, 'ball');
        // ball1.setVelocityX(100);

        // var balls = this.physics.add.group({
        //     defaultKey: 'ball',
        //     velocityX: 100
        // });

        // balls.create(0, 100);
        // balls.create(0, 200);

        // this.physics.add.collider(ball1, blocks, function (ball, block)
        // {
        // console.log('block velocity', block.body.velocity.x);
        // });

        const block = this.physics.add.image(400, 300, 'block');
        const ball = this.physics.add.image(200, 300, 'ball');

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

        // block.setVelocityX(-100);

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

// TODO

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

const game = new Phaser.Game(config);

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

Код начинается с создания класса сцены Example. В методе preload задается базовый URL для загрузки ресурсов и загружаются два изображения: спрайт блока (block) и спрайт шара (ball).

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. Блок размещается в центре экрана, а шар — левее. Оба объекта автоматически получают Arcade Physics тело.

const block = this.physics.add.image(400, 300, 'block');
const ball = this.physics.add.image(200, 300, 'ball');

Настройка массы и скорости

Ключевой момент — настройка массы шара с помощью метода setMass. Установив значение 10, мы делаем шар в 10 раз "тяжелее" по умолчанию (масса по умолчанию равна 1). Затем шару задается начальная горизонтальная скорость.

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

Блок в этом примере остается статичным (его скорость не задана), что делает его идеальной мишенью для демонстрации передачи импульса.

Обработка столкновений

Столкновение между шаром и блоком регистрируется с помощью this.physics.add.collider. Этот метод автоматически рассчитывает физику удара, учитывая массу, скорость и упругость объектов.

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

Из-за большой массы шара (10) при столкновении с легким блоком (масса 1) шар почти не изменит свою траекторию, а блок получит значительный импульс и отлетит. Если бы массы были равны, они отскочили бы друг от друга симметрично.

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

В конце кода создается конфигурационный объект config. Важно обратить внимание на настройки физического движка Arcade: debug: false отключает отладочную визуалицию, а useTree: false отключает оптимизацию пространственного разбиения для простоты в этом примере.

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

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

Масса — мощный инструмент для управления поведением объектов при столкновениях. Используйте setMass для создания тяжелых снарядов, неподвижных платформ или реалистичных шаров с разным весом. Для экспериментов попробуйте

  1. Установить блоку массу больше, чем у шара, и посмотреть, как шар отскочит
  2. Включить отладку (debug: true), чтобы видеть векторы скорости
  3. Добавить setBounce для создания супер-мячика