О чем этот пример
Работая с движком Phaser, разработчики часто используют спрайты и тайл-спрайты для графики. Однако стандартный `TileSprite` не имеет физического тела 'из коробки', что ограничивает его интерактивность. В этой статье мы разберем, как добавить физическое тело к TileSprite, чтобы он мог сталкиваться, отскакивать и реагировать на границы мира. Этот прием полезен для создания динамических фонов, разрушаемых стен или крупных составных объектов, состоящих из повторяющихся текстур.
Версия 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('crate', 'assets/sprites/crate32.png');
}
create ()
{
// Our dynamic TileSprite that will bounce around
const block = this.add.tileSprite(100, 100, 32 * 4, 32 * 2, 'crate');
this.physics.add.existing(block, false);
block.body.setVelocity(130, 180);
block.body.setBounce(1, 1);
block.body.setCollideWorldBounds(true);
// Our static TileSprite that will just receive collide events
const staticBlock = this.add.tileSprite(400, 300, 32 * 3, 32 * 8, 'crate');
this.physics.add.existing(staticBlock, true);
this.physics.add.collider(block, staticBlock);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
debug: true,
gravity: { y: 200 }
}
},
scene: Example
};
const game = new Phaser.Game(config);
Проблема: TileSprite без физики
Класс TileSprite в Phaser отлично подходит для отображения повторяющихся текстур — например, для кирпичной стены, травяного поля или крупного объекта, собранного из одного изображения. По умолчанию он является статическим графическим объектом.
const staticBlock = this.add.tileSprite(400, 300, 32 * 3, 32 * 8, 'crate');
Этот код создает тайл-спрайт, но он не будет реагировать на силу тяжести, не сможет сталкиваться с другими объектами и просто 'висит' на экране. Для игровой механики этого часто недостаточно.
Решение: Добавление физического тела
Phaser Arcade Physics предоставляет метод this.physics.add.existing(), который добавляет физическое тело к уже существующему игровому объекту. Это ключевой момент для 'оживления' TileSprite.
// Добавляем динамическое тело (второй параметр - false)
this.physics.add.existing(block, false);
// Добавляем статическое тело (второй параметр - true)
this.physics.add.existing(staticBlock, true);
Параметр isStatic определяет тип тела. Динамическое тело (false) будет двигаться под действием сил и столкновений. Статическое тело (true) остается неподвижным, но может участвовать в коллизиях.
Настройка динамического тела
После добавления тело становится доступным через свойство .body. Для динамического тела мы можем задать начальную скорость, упругость и включить столкновение с границами игрового мира.
block.body.setVelocity(130, 180); // Устанавливаем скорость по осям X и Y
block.body.setBounce(1, 1); // Задаем коэффициент отскока (1 - абсолютно упругий удар)
block.body.setCollideWorldBounds(true); // Включаем столкновение с границами сцены
Эти настройки заставляют наш тайл-спрайт двигаться, отскакивать от краев экрана и в конечном итоге — от других физических объектов.
Организация взаимодействий
Чтобы объекты реагировали друг на друга, нужно создать коллайдер. Метод this.physics.add.collider() регистрирует столкновение между двумя телами и обрабатывает его.
this.physics.add.collider(block, staticBlock);
В нашем примере динамический block будет отскакивать от статического staticBlock. Без этого вызова объекты могли бы проходить друг сквозь друга, несмотря на наличие физических тел.
Конфигурация сцены и физики
Важно не забыть активировать Arcade Physics в конфигурации игры. Без этого любые вызовы методов физики будут приводить к ошибкам.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
physics: { // Включаем физический движок
default: 'arcade',
arcade: {
debug: true, // Полезно для отладки: рисует контуры тел
gravity: { y: 200 } // Глобальная сила тяжести
}
},
scene: Example
};
Параметр debug: true временно включает визуализацию hitbox, что помогает убедиться в правильности размеров и положений тел.
Что попробовать дальше
Добавление физического тела к TileSprite — мощный прием, который значительно расширяет возможности этого графического объекта. Вы можете создавать движущиеся платформы с текстурой, разрушаемые стены из кирпичей или скроллящиеся фоны, взаимодействующие с игроком. Для экспериментов попробуйте изменить размеры тайл-спрайтов, поиграть с коэффициентами отскока или заставить несколько динамических блоков сталкиваться между собой, создавая сложные физические симуляции.
