О чем этот пример
При разработке игр с физикой часто возникает необходимость удалять объекты со сцены. Phaser с плагином Matter.js предоставляет для этого метод `destroy()`, но его применение имеет важные нюансы. В этой статье разберем, как корректно удалять тела, чтобы избежать ошибок и утечек памяти, на примере уничтожения статической платформы по клику мыши.
Версия 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('platform', 'assets/sprites/platform.png');
}
create ()
{
this.matter.add.image(325, -100, 'block');
this.matter.add.image(400, 300, 'block');
this.matter.add.image(450, 50, 'block');
const platform = this.matter.add.image(400, 550, 'platform', null, { isStatic: true });
console.log(platform);
this.input.once('pointerup', () =>
{
platform.destroy();
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#1b1464',
parent: 'phaser-example',
physics: {
default: 'matter'
},
scene: Example
};
const game = new Phaser.Game(config);
Настройка сцены и загрузка ассетов
В методе preload() мы загружаем два изображения, которые будут использоваться как физические тела. Обратите внимание на использование setBaseURL() – это удобно, если ваши ассеты хранятся в одном месте. В данном примере это удаленный репозиторий с примерами.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('block', 'assets/sprites/block.png');
this.load.image('platform', 'assets/sprites/platform.png');
}
Создание физических тел
В методе create() создаются четыре тела. Первые три – динамические блоки, которые упадут под действием гравитации. Четвертое тело – статическая платформа. Ключевые моменты:
1. `this.matter.add.image` создает игровой объект (`Image`) с физическим телом Matter.js.
2. Последний аргумент для платформы – `{ isStatic: true }` – делает тело неподвижным. Такие тела не подвержены силам и столкновениям, но могут быть уничтожены.
3. Объект `platform` сохраняется в константу для последующего доступа.
create ()
{
this.matter.add.image(325, -100, 'block');
this.matter.add.image(400, 300, 'block');
this.matter.add.image(450, 50, 'block');
const platform = this.matter.add.image(400, 550, 'platform', null, { isStatic: true });
console.log(platform);
}
Уничтожение тела по событию
Здесь происходит самое важное. Мы навешиваем одноразовый обработчик события клика (pointerup) на объект this.input. По срабатыванию события вызывается метод destroy() у объекта платформы.
Что делает destroy()?
1. Удаляет физическое тело (Matter.Body) из мира Matter.js.
2. Удаляет игровой объект (Phaser.GameObjects.Image) из текущей сцены и системы отображения.
3. Освобождает связанные с ним ресурсы.
Это предпочтительный способ удаления, а не простое скрытие объекта или отключение его физики.
this.input.once('pointerup', () =>
{
platform.destroy();
});
Конфигурация игры и физики
Для работы с физикой Matter.js необходимо правильно настроить конфиг игры. В блоке physics указывается default: 'matter'. Это инициализирует плагин Matter.js и делает его методы доступными через this.matter в сцене.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#1b1464',
parent: 'phaser-example',
physics: {
default: 'matter'
},
scene: Example
};
Что попробовать дальше
Метод destroy() – это стандартный и безопасный способ полного удаления игрового объекта вместе с его физическим телом в Phaser. Для экспериментов попробуйте: вызвать destroy() у динамического блока (он исчезнет при падении), удалить несколько тел по разным условиям (например, при выходе за границы экрана) или создать новую платформу после уничтожения старой.
