О чем этот пример
В игровой механике часто требуется менять свойства объектов в реальном времени — например, увеличивать врага после получения урона или растить собираемый предмет. В примере показано, как изменять масштаб физического тела в движке 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('blue', 'assets/sprites/columns-blue.png');
}
create ()
{
this.scale = 1.1;
this.matter.world.setBounds().disableGravity();
// By default it will create a rectangular body the size of the texture
const rect = this.matter.add.image(200, 50, 'blue');
// Just make the body move around and bounce
rect.setVelocity(3, 1);
rect.setAngularVelocity(0.01);
rect.setBounce(1);
rect.setFriction(0, 0, 0);
rect.setInteractive();
rect.on('pointerup', () =>
{
rect.setScale(this.scale);
this.scale += 0.1;
rect.setVelocity(Phaser.Math.Between(-4, 4), Phaser.Math.Between(-2, 2));
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#1b1464',
parent: 'phaser-example',
physics: {
default: 'matter',
matter: {
debug: true
}
},
scene: Example
};
const game = new Phaser.Game(config);
Настройка физики и создание тела
В примере используется физический плагин Matter.js, который настраивается в конфигурации игры. Ключевой параметр debug: true включает визуализацию тел для отладки.
physics: {
default: 'matter',
matter: {
debug: true
}
}
В методе create сцена инициализирует мир: границы устанавливаются методом setBounds, а гравитация отключается. Объект создаётся через this.matter.add.image, который автоматически генерирует прямоугольное тело по размеру текстуры 'blue'.
this.matter.world.setBounds().disableGravity();
const rect = this.matter.add.image(200, 50, 'blue');
Задание движения и интерактивности
Созданному телу сразу задаётся движение. Метод setVelocity устанавливает линейную скорость, а setAngularVelocity — вращательную. Параметры setBounce и setFriction настраивают упругость и трение: здесь отскок максимальный (`1), а трение отсутствует (0`).
rect.setVelocity(3, 1);
rect.setAngularVelocity(0.01);
rect.setBounce(1);
rect.setFriction(0, 0, 0);
Чтобы объект реагировал на клики, он делается интерактивным через setInteractive. Это стандартный подход Phaser для обработки указателя.
rect.setInteractive();
Обработка клика и изменение масштаба
При клике на объект срабатывает событие pointerup. В обработчике сначала меняется масштаб тела через setScale, используя переменную this.scale. Затем эта переменная увеличивается для следующего клика.
rect.on('pointerup', () => {
rect.setScale(this.scale);
this.scale += 0.1;
});
Важно: Matter.js автоматически обновляет границы коллизий тела при изменении масштаба. Это позволяет сохранять физические взаимодействия без ручного перерасчёта. После масштабирования телу задаётся новая случайная скорость через Phaser.Math.Between.
rect.setVelocity(Phaser.Math.Between(-4, 4), Phaser.Math.Between(-2, 2));
Что попробовать дальше
Изменение масштаба физического тела через setScale в Matter.js — простой способ динамически менять размеры объекта с сохранением коллизий. Для экспериментов попробуйте: анимировать масштабирование через tweens, применять его к составным телам, менять не только размер, но и плотность тела методом setDensity или создавать цепную реакцию при клике на несколько связанных объектов.
