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

В Arcade Physics движением объектов управляют не только силы вроде скорости или гравитации, но и трение — сопротивление поверхности. Параметр трения определяет, насколько быстро объект замедлится или сохранит импульс при контакте с другим телом. В этой статье мы разберем, как работает трение на практике, используя пример с леммингами и подвижными платформами. Вы научитесь контролировать инерцию игровых объектов, создавая более реалистичную или, наоборот, необычную физику для своих платформ.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    lemmings;
    platforms;

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('platform', 'assets/sprites/platform.png');
        this.load.image('lemming', 'assets/sprites/lemming.png');
        this.load.image('spikedball', 'assets/sprites/spikedball.png');
    }

    create ()
    {
        this.platforms = this.physics.add.group({
            key: 'platform',
            frameQuantity: 3,
            setXY: { x: 400, y: 150, stepY: 150 },
            velocityX: 60,
            immovable: true
        });

        const [ platform1, platform2, platform3 ] = this.platforms.getChildren();

        platform1.setFrictionX(1);
        platform2.setFrictionX(0.5);
        platform3.setFrictionX(0);

        this.lemmings = this.physics.add.group({ gravityY: 600 });

        this.lemmings.createMultiple([
            {
                key: 'lemming',
                repeat: 3,
                setXY: { x: 250, y: 0, stepX: 100 }
            },
            {
                key: 'lemming',
                repeat: 3,
                setXY: { x: 250, y: 200, stepX: 100 }
            },
            {
                key: 'lemming',
                repeat: 3,
                setXY: { x: 250, y: 350, stepX: 100 }
            }
        ]);

        this.physics.add.group({
            key: 'spikedball',
            frameQuantity: 6,
            setXY: { x: 0, y: 625, stepX: 150 },
            angularVelocity: 60
        });

        this.physics.add.collider(this.lemmings, this.platforms);
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    physics: { default: 'arcade' },
    scene: Example
};

const game = new Phaser.Game(config);

Настройка сцены и загрузка ресурсов

Класс Example расширяет Phaser.Scene и содержит две основные группы: lemmings (персонажи) и platforms (платформы). В методе preload загружаются три спрайта: платформа, лемминг и шипастый шар.

this.load.image('platform', 'assets/sprites/platform.png');
this.load.image('lemming', 'assets/sprites/lemming.png');
this.load.image('spikedball', 'assets/sprites/spikedball.png');

Создание платформ с разным трением

В методе create создается физическая группа platforms. Платформы располагаются вертикально с шагом 150 пикселей, имеют горизонтальную скорость (velocityX: 60) и помечены как неподвижные (immovable: true). Это значит, они не будут реагировать на столкновения с другими телами, но продолжат двигаться.

this.platforms = this.physics.add.group({
    key: 'platform',
    frameQuantity: 3,
    setXY: { x: 400, y: 150, stepY: 150 },
    velocityX: 60,
    immovable: true
});

Далее, для каждой платформы устанавливается разное значение трения по оси X с помощью метода setFrictionX. Первая платформа имеет максимальное трение (1), вторая — среднее (0.5), третья — нулевое (0). Трение влияет на то, насколько быстро лемминг замедлится, двигаясь по платформе.

const [ platform1, platform2, platform3 ] = this.platforms.getChildren();
platform1.setFrictionX(1);
platform2.setFrictionX(0.5);
platform3.setFrictionX(0);

Группа леммингов и их взаимодействие

Группа lemmings создается с вертикальной гравитацией (gravityY: 600). Лемминги появляются тремя рядами, каждый ряд содержит четырех персонажей (один оригинал + три повтора). Это сделано с помощью createMultiple, где для каждого ряда задается начальная позиция и шаг по X.

this.lemmings.createMultiple([
    {
        key: 'lemming',
        repeat: 3,
        setXY: { x: 250, y: 0, stepX: 100 }
    },
    {
        key: 'lemming',
        repeat: 3,
        setXY: { x: 250, y: 200, stepX: 100 }
    },
    {
        key: 'lemming',
        repeat: 3,
        setXY: { x: 250, y: 350, stepX: 100 }
    }
]);

Добавляется коллайдер между леммингами и платформами. Без него объекты проходили бы друг сквозь друга. Коллайдер обеспечивает физическое взаимодействие, где трение платформ начинает влиять на движение леммингов.

this.physics.add.collider(this.lemmings, this.platforms);

Декоративные элементы и конфигурация игры

Для визуального разнообразия создается группа шипастых шаров (spikedball). Они не участвуют в физике с леммингами, но имеют угловую скорость (angularVelocity: 60), что заставляет их вращаться. Это демонстрирует, как легко добавлять движущиеся декоративные объекты.

this.physics.add.group({
    key: 'spikedball',
    frameQuantity: 6,
    setXY: { x: 0, y: 625, stepX: 150 },
    angularVelocity: 60
});

Конфигурация игры включает Arcade Physics как систему по умолчанию. Это обязательный шаг для работы физических методов, таких как setFrictionX.

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    physics: { default: 'arcade' },
    scene: Example
};

Что попробовать дальше

Трение — мощный инструмент для тонкой настройки физики в Phaser. Экспериментируйте: попробуйте изменить трение динамически в зависимости от событий игры, добавьте setFrictionY для вертикальных поверхностей или создайте платформы, трение которых меняется со временем. Это откроет возможности для уникальных игровых механик, например, ледяных скользких участков или липких ловушек.