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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        const r1 = this.add.rectangle(200, 150, 148, 148, 0x6666ff);

        const r2 = this.add.rectangle(400, 150, 148, 148, 0x9966ff).setStrokeStyle(4, 0xefc53f);

        this.physics.add.existing(r1);
        this.physics.add.existing(r2);

        r1.body.velocity.x = 100;
        r1.body.velocity.y = 100;
        r1.body.bounce.x = 1;
        r1.body.bounce.y = 1;
        r1.body.collideWorldBounds = true;

        r2.body.velocity.x = -100;
        r2.body.velocity.y = 100;
        r2.body.bounce.x = 1;
        r2.body.bounce.y = 1;
        r2.body.collideWorldBounds = true;
    }
}

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

const game = new Phaser.Game(config);

Создание простых прямоугольников

Phaser предоставляет фабричные методы для быстрого создания игровых объектов. Метод this.add.rectangle() создает прямоугольник, задавая его позицию, размеры и цвет.

const r1 = this.add.rectangle(200, 150, 148, 148, 0x6666ff);

const r2 = this.add.rectangle(400, 150, 148, 148, 0x9966ff).setStrokeStyle(4, 0xefc53f);

Первый аргумент — координата X, второй — Y, затем ширина и высота, а последний — цвет в шестнадцатеричном формате. Второму прямоугольнику дополнительно задается обводка с помощью метода .setStrokeStyle(), где указывается толщина линии и её цвет. На этом этапе объекты — это просто графика без физических свойств.

Добавление физического тела

Чтобы объекты могли сталкиваться и двигаться под действием физики, им нужно добавить тело. В Arcade Physics для этого используется метод this.physics.add.existing(). Он добавляет к уже существующему игровому объекту компонент тела (Body).

this.physics.add.existing(r1);
this.physics.add.existing(r2);

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

Настройка скорости, отскока и границ

Через свойство body мы настраиваем поведение объектов. Зададим им начальную скорость, коэффициент упругости (отскок) и включим столкновение с границами мира.

r1.body.velocity.x = 100;
r1.body.velocity.y = 100;
r1.body.bounce.x = 1;
r1.body.bounce.y = 1;
r1.body.collideWorldBounds = true;

r2.body.velocity.x = -100;
r2.body.velocity.y = 100;
r2.body.bounce.x = 1;
r2.body.bounce.y = 1;
r2.body.collideWorldBounds = true;

Свойства velocity.x и velocity.y определяют начальную скорость по осям. Значение bounce, равное 1, означает абсолютно упругий отскок (без потери энергии). Установка collideWorldBounds в true заставляет объект оставаться в пределах, заданных в конфиге (width: 800, height: 600). Обратите внимание, что в конфиге также задана гравитация (gravity: { y: 200 }), поэтому объекты будут постоянно падать вниз, но отскакивать от нижней границы.

Важная конфигурация сцены

Чтобы вся эта физика работала, необходимо правильно инициализировать игру с активированной системой Arcade Physics.

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    physics: {
        default: 'arcade', // Включаем Arcade Physics как систему по умолчанию
        arcade: {
            gravity: { y: 200 } // Задаем силу гравитации, направленную вниз
        }
    },
    scene: Example // Указываем наш класс сцены
};

const game = new Phaser.Game(config);

Ключевой блок — physics. Указание default: 'arcade' подключает систему. Внутри arcade: {} можно задать глобальные параметры, такие как gravity или debug. Без этого блока вызов this.physics.add.existing() вызовет ошибку.

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

Всего за несколько строк кода мы создали два динамических прямоугольника, которые отскакивают от границ мира и друг от друга (столкновение между ними работает автоматически, так как оба имеют Arcade тела). Этот подход отлично подходит для быстрого прототипирования механик. Для экспериментов попробуйте: изменить коэффициенты bounce на значения меньше 1, чтобы объекты теряли энергию; отключить гравитацию в конфиге; добавить больше прямоугольников с разными скоростями и использовать методы setVelocity() или setBounce() для управления телом.