О чем этот пример
Физические движки в играх часто ограничены стандартными силами, такими как гравитация или ветер, действующими одинаково на все объекты. Но что, если вам нужно, чтобы определённый объект, подобно чёрной дыре или магниту, притягивал к себе остальные? Встроенный в Phaser Matter.js плагин Attractor позволяет легко реализовать такие кастомные силы притяжения между любыми телами. Эта статья покажет, как настроить плагин и создать объект-«солнце», которое будет притягивать к себе «пришельцев», открывая путь для механик гравитационных пуль, магнитных ловушек или орбитального движения.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
// const { Physics } = require("phaser");
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('sun', 'assets/tests/space/sun.png');
this.load.image('alien', 'assets/sprites/space-baddie.png');
}
create ()
{
// You can enable the Attractors plugin either via the game config (see above), or explicitly in code:
// this.matter.enableAttractorPlugin();
this.matter.world.setBounds();
this.aliens = this.matter.add.imageStack('alien', null, 0, 500, 50, 2, 0, 0, {
mass: 1,
ignorePointer: true
});
this.sun = this.matter.add.image(400, 200, 'sun', null, {
shape: {
type: 'circle',
radius: 64
},
attractors: [
(bodyA, bodyB) => ({
x: (bodyA.position.x - bodyB.position.x) * 0.000001,
y: (bodyA.position.y - bodyB.position.y) * 0.000001
})
]
});
this.matter.add.mouseSpring();
}
update ()
{
const bodies = this.aliens.bodies;
const force = { x: 0, y: -0.00001 };
for (let i = 0; i < bodies.length; i++)
{
// Phaser.Physics.Matter.Matter.Body.applyForce(bodies[i], bodies[i].position, force);
}
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
gravity: {
scale: 0
},
}
},
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и загрузка ассетов
В начале, как и в любом проекте Phaser, мы загружаем необходимые изображения. В методе preload указывается базовый URL и загружаются два спрайта: «солнце» и «пришелец». Важно, что для корректной работы плагина Attractor используется физический движок Matter.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('sun', 'assets/tests/space/sun.png');
this.load.image('alien', 'assets/sprites/space-baddie.png');
}
Настройка физического мира и создание тел
В методе create мы настраиваем мир. Строка this.matter.world.setBounds() создаёт границы по краям игрового поля. Далее создаётся группа тел — стопка спрайтов «пришельцев» с помощью this.matter.add.imageStack. Параметры задают текстуру, начальные координаты, количество спрайтов в рядах и столбцах, а также их физические свойства, такие как mass (масса).
create ()
{
this.matter.world.setBounds();
this.aliens = this.matter.add.imageStack('alien', null, 0, 500, 50, 2, 0, 0, {
mass: 1,
ignorePointer: true
});
Затем создаётся ключевой объект — «солнце». Обратите внимание на опцию shape, которая определяет физическую форму тела (круг), и, самое главное, массив attractors.
this.sun = this.matter.add.image(400, 200, 'sun', null, {
shape: {
type: 'circle',
radius: 64
},
attractors: [
(bodyA, bodyB) => ({
x: (bodyA.position.x - bodyB.position.x) * 0.000001,
y: (bodyA.position.y - bodyB.position.y) * 0.000001
})
]
});
Как работает Attractor функция
Массив attractors содержит одну или несколько функций. Каждая функция автоматически вызывается движком Matter для расчёта силы притяжения между двумя телами: bodyA (тело, к которому привязан аттрактор — наше «солнце») и bodyB («пришелец» или любое другое тело в мире). Функция должна вернуть объект с вектором силы { x, y }, который будет применён к bodyB.
В нашем примере сила рассчитывается просто: разница координат по осям X и Y умножается на очень маленький коэффициент (0.000001). Эта формула создаёт силу, направленную от bodyB («пришельца») к bodyA («солнцу»), так как вектор строится как (positionA - positionB). Чем ближе тела, тем меньше разница координат и слабее сила, что имитирует классическое гравитационное притяжение.
Включение плагина и вспомогательные инструменты
Плагин Attractor может быть включён глобально в конфигурации игры (как показано в исходном коде примера через plugins), либо непосредственно в коде сцены с помощью this.matter.enableAttractorPlugin(). В данном примере он уже включён через конфиг.
Строка this.matter.add.mouseSpring() добавляет пружину, привязанную к курсору мыши, что позволяет вручную взаимодействовать с телами и наглядно видеть, как они притягиваются к «солнцу».
this.matter.add.mouseSpring();
}
Глобальная конфигурация игры
Ключевой момент для работы примера — правильная настройка физики Matter в конфиге игры. Обратите внимание: гравитация отключена (gravity: { scale: 0 }). Это важно, чтобы единственной силой, действующей на «пришельцев», было притяжение от «солнца». Если включить стандартную гравитацию, тела будут также падать вниз.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
gravity: {
scale: 0
},
plugins: {
attractors: true
}
}
},
scene: Example
};
Что попробовать дальше
Плагин Attractor в Phaser — это мощный и гибкий инструмент для создания нестандартных физических взаимодействий. Вы можете привязать функцию-аттрактор к любому телу, будь то планета, магнит или вакуумная воронка. Для экспериментов попробуйте: изменить формулу силы для создания отталкивания (repulsor), сделать силу зависимой от расстояния по квадратичному закону (реалистичная гравитация), добавить нескольким объектам разные аттракторы или динамически включать/отключать притяжение при определённых событиях в игре.
