О чем этот пример
Создание интерактивных симуляций, где игрок может рисовать объекты, которые сразу подчиняются законам физики, открывает двери для уникальных игровых механик. В этой статье мы разберем пример из официальной документации Phaser, который позволяет рисовать треугольники, падающие и отскакивающие в мире Matter.js. Вы научитесь обрабатывать ввод пользователя для создания тел, контролировать частоту их появления и настраивать физические свойства для создания реалистичного поведения.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
create ()
{
this.matter.world.setBounds();
const triSize = 8;
const lastPosition = new Phaser.Math.Vector2();
const options = { friction: 0.005, frictionAir: 0, restitution: 1 };
this.input.on('pointerdown', function (pointer)
{
lastPosition.x = pointer.x;
lastPosition.y = pointer.y;
this.matter.add.polygon(pointer.x, pointer.y, 3, triSize, options);
}, this);
this.input.on('pointermove', function (pointer)
{
if (pointer.isDown)
{
const x = pointer.x;
const y = pointer.y;
if (Phaser.Math.Distance.Between(x, y, lastPosition.x, lastPosition.y) > triSize * 1.5)
{
lastPosition.x = x;
lastPosition.y = y;
this.matter.add.polygon(pointer.x, pointer.y, 3, triSize, options);
}
}
}, this);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
gravity: {
y: 0.02
},
enableSleep: true,
debug: true
}
},
scene: Example
};
const game = new Phaser.Game(config);
Настройка сцены и Matter.js
Ключ к работе с физикой в Phaser — правильная конфигурация. В примере используется движок Matter.js, который является одним из самых мощных и гибких.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
gravity: { y: 0.02 },
enableSleep: true,
debug: true
}
},
scene: Example
};
В блоке physics.matter задаются важные параметры: слабая гравитация по оси Y (gravity: { y: 0.02 }), флаг enableSleep, который отключает расчеты для неподвижных тел для оптимизации, и debug: true, который отображает контуры тел для отладки. В методе create() сцены устанавливаются границы мира вызовом this.matter.world.setBounds(), чтобы тела не улетали за пределы холста.
Создание тела по клику мыши
Основная логика реагирует на события ввода. При нажатии кнопки мыши (pointerdown) создается физическое тело в форме треугольника.
this.input.on('pointerdown', function (pointer) {
lastPosition.x = pointer.x;
lastPosition.y = pointer.y;
this.matter.add.polygon(pointer.x, pointer.y, 3, triSize, options);
}, this);
Функция this.matter.add.polygon() создает многоугольное тело. Ее аргументы: координаты X и Y (берем из позиции указателя pointer), количество сторон (3 для треугольника), радиус описанной окружности (triSize = 8) и объект с физическими свойствами options. Сразу же запоминаем позицию этого клика в векторе lastPosition — это нужно для следующего шага.
Контролируемое рисование при зажатой кнопке
Чтобы при движении мыши с зажатой кнопкой треугольники появлялись не сплошным потоком, а с некоторым интервалом, используется событие pointermove и проверка расстояния.
this.input.on('pointermove', function (pointer) {
if (pointer.isDown) {
const x = pointer.x;
const y = pointer.y;
if (Phaser.Math.Distance.Between(x, y, lastPosition.x, lastPosition.y) > triSize * 1.5) {
lastPosition.x = x;
lastPosition.y = y;
this.matter.add.polygon(pointer.x, pointer.y, 3, triSize, options);
}
}
}, this);
Новое тело создается только если расстояние от последней записанной позиции (lastPosition) до текущей позиции курсора превышает порог (triSize * 1.5). Это предотвращает "засорение" мира огромным количеством тел в одной точке и создает эффект цепочки треугольников с равными промежутками. Метод Phaser.Math.Distance.Between() используется для расчета этого расстояния.
Настройка физических свойств тел
Поведение созданных треугольников — их отскоки и трение — определяется объектом options, который передается в this.matter.add.polygon().
const options = { friction: 0.005, frictionAir: 0, restitution: 1 };
* friction: 0.005 — устанавливает очень низкое трение о поверхности других тел. Треугольники будут легко скользить.
* frictionAir: 0 — полностью отключает сопротивление воздуха. Тела не будут замедляться в полете.
* restitution: 1 — задает коэффициент упругости (отскока) равный 1. Это означает, что тело при столкновении сохраняет всю кинетическую энергию, отскакивая практически без потерь, как идеально упругий мяч. В сочетании с почти нулевым трением это создает долгий, хаотичный и зрелищный процесс взаимодействия тел.
Что попробовать дальше
Этот пример демонстрирует мощную связку интерактивности и физики в Phaser. Всего в нескольких десятках строк кода создается основа для игровых механик, таких как строительство неустойчивых башен, рисование ловушек или создание интерактивных песочниц. Для экспериментов попробуйте изменить параметры в объекте options, например, увеличьте friction для "липких" объектов или уменьшите restitution для "мягких" отскоков. Замените polygon на circle или rectangle, чтобы рисовать другие фигуры, или свяжите создание тел с удержанием определенной клавиши для более сложного управления.
