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

При создании аркадных игр часто требуется управлять множеством однотипных объектов — снарядами, врагами, частицами. Ручное управление каждым из них через циклы неэффективно. В этой статье разберем, как использовать мощный метод `setVelocityY()` для физической группы (Group) в движке Arcade Physics, чтобы одним вызовом привести в движение или изменить поведение десятков спрайтов. Этот подход критически важен для оптимизации и чистоты кода в проектах с большим количеством динамических объектов.

Версия 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('ball', 'assets/demoscene/ball-tlb.png');
    }

    create ()
    {
        const group = this.physics.add.group({
            key: 'ball',
            frameQuantity: 28,
            gridAlign: {
                x: 14,
                y: 14,
                width: 28,
                height: 1,
                cellWidth: 28
            },
            bounceY: 1,
            collideWorldBounds: true
        });

        group.setVelocityY(300, 10);
    }
}

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

const game = new Phaser.Game(config);

Создаем физическую группу объектов

В Phaser группа (Group) — это пул объектов (чаще всего спрайтов), которыми можно управлять как единым целым. Использование физического движка Arcade добавляет объектам в группе свойства тела (body), такие как скорость, ускорение и столкновения.

В примере мы создаем группу из 28 шаров (ball). Ключевые параметры конфигурации: - key: текстура для спрайтов. - frameQuantity: общее количество создаваемых объектов. - gridAlign: автоматическое выравнивание объектов в сетке. Параметры width: 28 и height: 1 создают горизонтальный ряд из 28 шаров. - bounceY и collideWorldBounds: определяют физическое поведение — отскок от границ мира.

const group = this.physics.add.group({
    key: 'ball',
    frameQuantity: 28,
    gridAlign: {
        x: 14,
        y: 14,
        width: 28,
        height: 1,
        cellWidth: 28
    },
    bounceY: 1,
    collideWorldBounds: true
});

Метод group.setVelocityY() — массовое управление

Вот где проявляется сила групп. Вместо перебора всех объектов в цикле group.getChildren() и ручного задания body.velocity.y, мы используем один метод.

group.setVelocityY(velocityY, step) принимает два аргумента: 1. velocityY (обязательный): значение скорости по оси Y, которое будет применено. 2. step (опциональный): шаг, на который будет изменяться скорость для каждого последующего объекта в группе. Это создает градиент или волну движения.

В нашем примере все 28 шаров получат начальную вертикальную скорость 300 пикселей в секунду вниз (т.к. в конфиге задана гравитация gravity: { y: 100 }). Из-за отскока (bounceY: 1) и столкновения с границами мира (collideWorldBounds: true) они будут весело прыгать.

group.setVelocityY(300, 10);

Если бы мы не использовали группы, код выглядел бы громоздко:

const children = group.getChildren();
for (let i = 0; i < children.length; i++) {
    children[i].body.velocity.y = 300 + (i * 10); // Эмуляция шага
}

Почему это работает и как использовать step

Метод setVelocityY() (как и его брат setVelocityX()) работает напрямую с телами Arcade Physics всех активных объектов в группе. Это внутренний, оптимизированный механизм Phaser.

Параметр step — это «изюминка». В примере step равен 10. Это значит, что первый шар получит скорость 300, второй — 310, третий — 320 и так далее. Визуально это создает эффект последовательного, «волнообразного» начала движения, что отлично подходит для анимаций пуль, цепочек врагов или каскадных эффектов.

Если step не указан, все объекты получат одинаковую скорость. Это полезно для одновременного запуска снарядов или задания общего вектора движения для стаи врагов.

Важно помнить, что метод применяется только к объектам, у которых уже существует физическое тело (body). Группа, созданная через this.physics.add.group(), гарантирует это.

Конфигурация сцены и физики

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

- physics.default: 'arcade' подключает движок. - Внутри arcade мы отключаем отладку (debug: false) и задаем гравитацию по оси Y. Именно гравитация в сочетании с заданной нами скоростью 300 определяет начальную динамику шаров.

Конфигурация сцены (scene: Example) связывает наш класс с игрой.

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

const game = new Phaser.Game(config);

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

Использование group.setVelocityY() — это эталонный подход для эффективного управления физическими свойствами множества объектов в Phaser. Он сокращает код, повышает производительность и открывает двери для создания сложных паттернов движения через параметр step. **Идеи для экспериментов:** 1. Замените setVelocityY на setVelocityX и наблюдайте, как шары летят горизонтально, отскакивая от боковых стенок. 2. Скомбинируйте оба метода, чтобы задать диагональное движение. 3. Поиграйте со значением step, установив его отрицательным, чтобы создать обратную волну. 4. Вызовите setVelocityY по событию клика мыши, чтобы группа реагировала на действия игрока. 5. Создайте две группы с разными текстурами и скоростями, чтобы симулировать взаимодействие разных типов частиц.