О чем этот пример
Стандартные объекты вроде спрайтов легко превращаются в физические тела. Но что делать с текстом? В этом примере мы рассмотрим, как привязать полноценный физический движок Matter.js к объекту BitmapText. Это открывает путь к созданию интерактивных текстовых элементов, которые могут падать, отскакивать и сталкиваться, что идеально подходит для игровых меню, титров или разрушаемых интерфейсов. Мы разберем ключевой метод `this.matter.add.gameObject()`, который позволяет наделить физическими свойствами практически любой игровой объект, включая текст. Это мощный прием, расширяющий ваши возможности по созданию динамичных и визуально интересных сцен.
Версия 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('platform', 'assets/sprites/platform.png');
this.load.bitmapFont('desyrel', 'assets/fonts/bitmap/desyrel.png', 'assets/fonts/bitmap/desyrel.xml');
}
create ()
{
const text = this.add.bitmapText(140, -100, 'desyrel', 'Phaser 3');
this.matter.add.gameObject(text, { render: { sprite: { yOffset: 0.2 } } });
text.setFrictionAir(0.001);
text.setBounce(0.9);
this.matter.add.image(350, 450, 'platform', null, { isStatic: true }).setScale(2, 0.5).setAngle(10);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#1b1464',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
debug: true,
gravity: {
y: 0.3
}
}
},
scene: Example
};
const game = new Phaser.Game(config);
Настройка сцены и загрузка ресурсов
В методе preload() мы загружаем два ресурса: изображение платформы и bitmap-шрифт. Обратите внимание на использование this.load.setBaseURL() для указания базового пути — это упрощает загрузку из удаленного репозитория.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('platform', 'assets/sprites/platform.png');
this.load.bitmapFont('desyrel', 'assets/fonts/bitmap/desyrel.png', 'assets/fonts/bitmap/desyrel.xml');
}
Bitmap-шрифт загружается из двух файлов: изображения (.png) с набором символов и XML-файла (.xml), описывающего расположение каждого символа на этом изображении. Это классический формат для растровых шрифтов в играх.
Создание текста с физикой
В методе create() мы сначала создаем объект текста с помощью this.add.bitmapText(). Ключевая координата y: -100 размещает текст за верхней границей экрана, чтобы он упал вниз при старте сцены.
const text = this.add.bitmapText(140, -100, 'desyrel', 'Phaser 3');
Затем происходит самое важное: мы добавляем к этому текстовому объекту физическое тело движка Matter.js с помощью метода this.matter.add.gameObject(). Первым аргументом передается сам игровой объект (text), а вторым — конфигурация.
this.matter.add.gameObject(text, { render: { sprite: { yOffset: 0.2 } } });
Параметр render.sprite.yOffset смещает точку привязки (origin) физического тела относительно спрайта (или текста). Значение 0.2 немного опускает физическое тело вниз, что может помочь лучше выровнять визуальное и физическое представление для конкретного шрифта.
После этого текстовый объект text получает доступ ко всем методам физического тела. Мы настраиваем его свойства: очень низкое сопротивление воздуха (setFrictionAir(0.001)) для почти невесомого падения и высокий коэффициент упругости (setBounce(0.9)) для энергичных отскоков.
text.setFrictionAir(0.001);
text.setBounce(0.9);
Создание статической платформы
Чтобы текст не улетел в бездну, создадим для него препятствие — наклонную платформу. Мы используем this.matter.add.image(), который сразу создает и изображение, и привязанное к нему физическое тело.
this.matter.add.image(350, 450, 'platform', null, { isStatic: true }).setScale(2, 0.5).setAngle(10);
Ключевые моменты в этой строке:
1. Пятый аргумент — объект конфигурации тела. Флаг isStatic: true делает платформу неподвижной. На нее будут действовать столкновения, но гравитация и импульсы не смогут ее сдвинуть.
2. Метод .setScale(2, 0.5) растягивает изображение платформы по ширине (в 2 раза) и сжимает по высоте (в 0.5 раза).
3. Метод .setAngle(10) поворачивает платформу на 10 градусов, создавая наклонную поверхность для отскоков.
Теперь у падающего текста есть динамичная и непредсказуемая поверхность для взаимодействия.
Конфигурация Matter.js
Вся магия физики активируется в конфигурации игры. В блоке physics мы указываем движок matter как движок по умолчанию.
physics: {
default: 'matter',
matter: {
debug: true,
gravity: {
y: 0.3
}
}
}
Настройки движка Matter.js:
* debug: true — включает отладочную визуализацию. Вы увидите контуры физических тел (текста и платформы), что невероятно полезно для тонкой настройки столкновений и проверки размеров.
* gravity: { y: 0.3 } — задает силу гравитации по оси Y. Значение 0.3 относительно слабое, что позволяет наблюдать за падением и отскоками в замедленном, более управляемом темпе.
Что попробовать дальше
Метод this.matter.add.gameObject() — это мост между визуальным представлением и физической симуляцией. Он позволяет быстро "оживить" такие объекты, как BitmapText, Container или TileSprite, наделяя их физическими свойствами. Для экспериментов попробуйте:
1. Заменить BitmapText на текстовый объект, созданный через this.add.text(), и посмотрите, как поведет себя физика с векторным шрифтом.
2. Создать несколько текстовых тел с разными словами и настроить между ними столкновения (setCollisionCategory, setCollidesWith).
3. Добавить интерактивность: сделать текст кликабельным и при клике применять к нему силу (applyForce) или импульс (setVelocity).
