О чем этот пример
Физический движок Matter.js в Phaser открывает двери для создания удивительно динамичных и отзывчивых игровых миров. В этой статье мы разберем пример, где интерактивность достигается не через стандартные обработчики событий, а через физическое взаимодействие объектов, управляемое курсором мыши. Вы научитесь создавать массу легковесных частиц, настраивать их физические свойства и добавлять универсальный инструмент для их "перемешивания" — все это ключевые элементы для прототипирования игровых механик, симуляций или просто визуально приятных интерактивных демо.
Версия 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('blue', 'assets/particles/blue.png');
}
create ()
{
this.matter.world.setBounds(0, 0, 800, 550);
for (let i = 0; i < 256; i++)
{
const particle = this.matter.add.image(
Phaser.Math.Between(0, 800),
Phaser.Math.Between(0, 400),
'blue', null,
{ shape: { type: 'polygon', radius: 18 }, ignorePointer: true }
);
particle.setScale(0.8);
particle.setBlendMode('ADD');
particle.setFriction(0.005);
particle.setBounce(0.8);
particle.setMass(1);
}
this.matter.add.image(400, 0, 'block').setBounce(0.8).setMass(60);
this.matter.add.mouseSpring();
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
physics: {
default: 'matter'
},
scene: Example
};
const game = new Phaser.Game(config);
Настраиваем сцену и загружаем ресурсы
Вся работа начинается в методе preload(). Здесь мы загружаем два изображения, которые будут использоваться в качестве спрайтов для физических тел. Обратите внимание на использование setBaseURL — это удобный способ указать общий путь для всех загружаемых ресурсов.
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('block', 'assets/sprites/block.png');
this.load.image('blue', 'assets/particles/blue.png');
Создание физического мира и частиц
В методе create() мы сначала устанавливаем границы мира Matter.js. Это важно, чтобы наши частицы не улетали в бесконечность.
this.matter.world.setBounds(0, 0, 800, 550);
Затем в цикле создается 256 физических частиц. Ключевой метод здесь — this.matter.add.image. Он создает не просто спрайт, а физическое тело в форме изображения. Параметры shape и ignorePointer задаются в конфигурационном объекте.
const particle = this.matter.add.image(
Phaser.Math.Between(0, 800),
Phaser.Math.Between(0, 400),
'blue', null,
{ shape: { type: 'polygon', radius: 18 }, ignorePointer: true }
);
* Phaser.Math.Between случайным образом разбрасывает частицы по области.
* shape: { type: 'polygon', radius: 18 } определяет коллизионную форму тела как многоугольник, аппроксимирующий круг заданного радиуса. Это точнее, чем стандартный прямоугольник (AABB).
* ignorePointer: true указывает, что на само тело не будут реагировать события мыши (перетаскивание будет реализовано иначе).
После создания каждой частицы настраиваются ее физические свойства. Эти настройки определяют, как будет себя вести наша "жидкая" среда.
particle.setScale(0.8);
particle.setBlendMode('ADD');
particle.setFriction(0.005);
particle.setBounce(0.8);
particle.setMass(1);
* setBlendMode('ADD') дает яркий, "светящийся" визуальный эффект при наложении частиц.
* Крайне низкое трение (friction: 0.005) позволяет частицам долго скользить.
* Высокий коэффициент упругости (bounce: 0.8) делает отскоки энергичными.
* Одинаковая масса (mass: 1) упрощает предсказуемость взаимодействий.
Добавляем тяжелый объект и интерактивность
После создания облака частиц добавляется один крупный объект — блок. Он имеет значительную массу (60), что позволяет ему эффективно "расталкивать" легкие частицы при падении.
this.matter.add.image(400, 0, 'block').setBounce(0.8).setMass(60);
Вся магия интерактивности заключается в одной строке кода. Метод this.matter.add.mouseSpring() создает невидимую пружину (джойнт), которая связывает курсор мыши с ближайшим физическим телом в мире Matter.js при зажатой кнопке. Это позволяет вам буквально "зацепить" и тянуть, толкать, бросать любые объекты на сцене, включая наш тяжелый блок.
this.matter.add.mouseSpring();
Это гораздо более мощный и физически достоверный способ взаимодействия, чем простое переопределение координат спрайта.
Конфигурация игры и запуск
Код завершается стандартной для Phaser конфигурацией игры. Ключевой момент здесь — настройка физики. Мы явно указываем, что движком по умолчанию должен быть 'matter'.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
physics: { // Включаем и настраиваем физику Matter.js
default: 'matter'
},
scene: Example
};
const game = new Phaser.Game(config);
Без этой настройки методы this.matter.* были бы не доступны.
Что попробовать дальше
Всего в нескольких десятках строк кода мы создали сложную, живую физическую систему, управляемую игроком. Это отличная основа для экспериментов. Попробуйте изменить количество частиц, их массу, трение и упругость, чтобы получить совершенно разные материалы — от густой жидкости до прыгучих шариков. Добавьте больше тяжелых объектов разных форм или создайте статичные препятствия с помощью this.matter.add.rectangle. Используйте setVelocity для придания частицам начального импульса и создания вихрей. Возможности ограничены только вашей фантазией.
