О чем этот пример
При создании сложных игровых объектов часто возникает ситуация, когда визуальное представление (спрайт) не совпадает с физической формой (collider). Это может быть необходимо для анимаций, поворотов или стилистических решений. В примере из официального репозитория Phaser демонстрируется, как корректно отделить спрайт треугольника от его физического тела с помощью смещения (offset), используя мощь физического движка Matter.js. Эта техника позволяет создавать более реалистичные и визуально привлекательные взаимодействия, сохраняя при этом точность физических столкновений.
Версия 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('triangle', 'assets/sprites/triangle.png');
this.load.image('platform', 'assets/sprites/platform.png');
}
create ()
{
const shapes = {
triangle: [
[ {x: 99,y: 79}, {x: 77,y: 118}, {x: 124,y: 118} ]
]
};
const triangle = this.matter.add.sprite(400, 100, 'triangle', null, {
shape: { type: 'fromVerts', verts: shapes.triangle },
render: { sprite: { xOffset: 0.30, yOffset: 0.15 } }
});
triangle.setAngle(16);
triangle.setBounce(0.9);
this.matter.add.image(400, 550, 'platform', null, { isStatic: true });
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#1b1464',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
gravity: { y: 0.6 },
debug: true
}
},
scene: Example
};
const game = new Phaser.Game(config);
Загрузка ресурсов и определение формы
В методе preload загружаются два изображения: спрайт треугольника и платформы. Ключевой момент происходит в create. Для физического тела треугольника используется не стандартный прямоугольник (bounding box), а произвольная форма, заданная вершинами (vertices). Это позволяет физике точно соответствовать визуальной форме спрайта.
const shapes = {
triangle: [
[ {x: 99,y: 79}, {x: 77,y: 118}, {x: 124,y: 118} ]
]
};
Массив shapes.triangle содержит один полигон (массив точек), описывающий треугольник. Координаты вершин заданы относительно центра спрайта. Это стандартный способ задания сложных форм в Matter.js через опцию shape.
Создание спрайта со смещением и кастомной формой
Спрайт создается с помощью this.matter.add.sprite. Пятый параметр — это конфигурационный объект для настройки Matter.js. Именно здесь происходит магия.
const triangle = this.matter.add.sprite(400, 100, 'triangle', null, {
shape: { type: 'fromVerts', verts: shapes.triangle },
render: { sprite: { xOffset: 0.30, yOffset: 0.15 } }
});
В опции shape указывается, что форма (Body) должна быть создана "из вершин" (fromVerts), используя массив verts. Опция render.sprite не влияет на физику, она управляет только отрисовкой. Параметры xOffset и yOffset смещают точку отрисовки спрайта относительно центра физического тела. Значения 0.30 и 0.15 означают смещение на 30% ширины и 15% высоты спрайта соответственно. Это позволяет визуально "поднять" треугольник, чтобы его острие совпадало с вершиной физического тела.
Настройка поведения и статичная платформа
После создания задаются базовые физические свойства.
triangle.setAngle(16);
triangle.setBounce(0.9);
Метод setAngle поворачивает физическое тело (и, как следствие, спрайт) на 16 градусов. setBounce устанавливает коэффициент упругости (отскока) равным 0.9, что делает объект очень "прыгучим".
this.matter.add.image(400, 550, 'platform', null, { isStatic: true });
Платформа создается как статичное тело (isStatic: true). Это означает, что она не подвержена силам гравитации или импульсам от других тел, выполняя роль неподвижной поверхности или стены.
Конфигурация игры и физики Matter
Конфигурация игры включает настройку физического движка Matter.js.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#1b1464',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
gravity: { y: 0.6 },
debug: true
}
},
scene: Example
};
В блоке physics.matter задается гравитация по оси Y (gravity: { y: 0.6 }). Включение debug: true — крайне полезная опция при разработке. Она отображает контуры всех физических тел (в нашем случае — треугольник по заданным вершинам и платформу), позволяя визуально убедиться, что форма и смещение спрайта настроены корректно.
Что попробовать дальше
Использование смещения спрайта (xOffset, yOffset) в связке с кастомной физической формой — мощный инструмент для тонкой настройки визуала и физики объектов. Это особенно актуально для несимметричных спрайтов или сложных анимаций. Для экспериментов попробуйте изменить значения смещения на отрицательные, чтобы сместить спрайт в другую сторону. Или задайте более сложную форму из нескольких полигонов для составного тела, также применив к нему смещение спрайта. Отключите debug: false, чтобы увидеть финальный визуальный результат без отладочной информации.
