О чем этот пример

В физическом движке 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) в примере и увидите, как поведение кардинально изменится. Или создайте сцену, где несколько «неподвижных» тел с разными скоростями сталкиваются друг с другом — они будут проходить сквозь взаимодействие, как призраки, так как ни одно не хочет уступать.