О чем этот пример
В физическом движке Phaser Arcade свойство `immovable` — мощный инструмент для управления столкновениями. Оно позволяет создать тело, которое при ударе о другие объекты не отскакивает и не меняет свою траекторию под влиянием импульса, но при этом может свободно двигаться с заданной скоростью. Это полезно для создания платформ, стен, которые могут двигаться, или главных персонажей, которые должны "расталкивать" окружение, не получая отдачи.
Версия 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('atari', 'assets/sprites/atari130xe.png');
this.load.image('diamond', 'assets/sprites/diamond.png');
}
create ()
{
// An "immovable" body never separates or bounces during a collision.
// It can still move by velocity.
const atari = this.physics.add.image(400, 300, 'atari')
.setBounce(1, 1)
.setCollideWorldBounds(true)
.setImmovable(true)
.setVelocity(200, 100);
const gems = this.physics.add.group({
key: 'diamond',
quantity: 24,
collideWorldBounds: true
});
Phaser.Actions.PlaceOnCircle(gems.getChildren(), new Phaser.Geom.Circle(400, 300, 200));
this.physics.add.collider(atari, gems);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: { debug: false }
},
scene: Example
};
const game = new Phaser.Game(config);
Что такое `setImmovable(true)`?
Метод setImmovable() устанавливает для физического тела флаг «неподвижности». Это не запрещает телу двигаться — вы по-прежнему можете задавать ему скорость (setVelocity). Ключевой эффект проявляется при обработке столкновений через collider.
Когда «неподвижное» тело сталкивается с обычным, система физики игнорирует передачу импульса от столкновения для этого тела. Неподвижное тело продолжит движение по своей первоначальной траектории, в то время как обычное тело отскочит или будет вытолкнуто, согласно законам физики Arcade.
const platform = this.physics.add.image(400, 300, 'atari')
.setImmovable(true)
.setVelocity(100, 0);
Разбор примера: летающий «Атари» и бриллианты
В предоставленном примере создаются два типа объектов: одно «неподвижное» тело (спрайт «Atari») и группа обычных тел (бриллианты).
Сначала настраивается главный объект atari. Ему задается отскок, включена проверка столкновений с границами мира, и, что самое важное, устанавливается флаг immovable. Несмотря на это, объекту сразу же задается начальная скорость.
const atari = this.physics.add.image(400, 300, 'atari')
.setBounce(1, 1)
.setCollideWorldBounds(true)
.setImmovable(true)
.setVelocity(200, 100);
Затем создается группа gems из 24 бриллиантов. Они расставляются по окружности с помощью Phaser.Actions.PlaceOnCircle. Все они являются обычными динамическими телами.
const gems = this.physics.add.group({
key: 'diamond',
quantity: 24,
collideWorldBounds: true
});
Phaser.Actions.PlaceOnCircle(gems.getChildren(), new Phaser.Geom.Circle(400, 300, 200));
Магия коллайдера: кто кого отталкивает
Взаимодействие между объектами регистрируется одной строкой кода, создающей коллайдер.
this.physics.add.collider(atari, gems);
При запуске сцены «Atari» летит и врезается в бриллианты. Поскольку для atari установлено immovable: true, столкновения влияют только на бриллианты. «Atari» продолжает двигаться по прямой, отскакивая только от границ мира, а бриллианты разлетаются в стороны от удара. Если бы флаг immovable не был установлен, «Atari» тоже менял бы направление при каждом столкновении с бриллиантом, и его движение было бы хаотичным.
Практическое применение и типичные сценарии
Свойство immovable незаменимо в ряде игровых механик:
* **Движущиеся платформы:** Платформа может ехать по рельсам, сталкиваясь с игроком и увлекая его за собой, при этом сама не сходит с траектории от удара. * **Толкающиеся персонажи:** Главный герой в top-down игре может расталкивать ящики или врагов, не отскакивая сам от них. * **Оружие и снаряды:** Тяжелый таран или шаровая молния, которая должна пробивать строй врагов, не меняя курса.
Важно помнить: immovable работает только в паре с collider. При использовании overlap (пересечения) физическая реакция не вычисляется, и флаг не имеет эффекта.
Что попробовать дальше
Свойство setImmovable(true) — это не про обездвиживание, а про контроль над импульсом в столкновениях. Оно позволяет создавать тела, которые являются активной, «непоколебимой» силой в физическом мире игры. Для экспериментов попробуйте убрать вызов .setImmovable(true) в примере и увидите, как поведение кардинально изменится. Или создайте сцену, где несколько «неподвижных» тел с разными скоростями сталкиваются друг с другом — они будут проходить сквозь взаимодействие, как призраки, так как ни одно не хочет уступать.
