Аттракторы и отталкиватели

Phaser — мощная библиотека для создания интерактивных 2D-приложений на JavaScript, предоставляющая развитую систему управления физикой объектов. Аттракторы и отталкиватели (англ. attractors и repellers) позволяют управлять движением спрайтов, создавая эффекты притяжения и отталкивания, что особенно полезно для симуляций, игр с гравитацией и систем частиц.


Основные концепции

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

Отталкиватель — объект, который отталкивает другие объекты, создавая эффект силы, направленной от центра. Применяется для создания зон избегания, столкновений или защитных полей.

Формула силы обычно описывается как:

[ = k ]

где:

  • () — вектор от объекта к аттрактору;
    1. — коэффициент силы (положительный для притяжения, отрицательный для отталкивания);
    1. — степень зависимости от расстояния (обычно 2 для физически реалистичных эффектов).

Настройка сцены и физики

Для реализации притяжения или отталкивания необходимо использовать физический движок Phaser, например Arcade Physics или Matter.js.

Пример создания сцены с Arcade Physics:

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 0 },
            debug: true
        }
    },
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

const game = new Phaser.Game(config);

let particles;
let attractor;

function preload() {
    this.load.image('particle', 'assets/particle.png');
}

function create() {
    particles = this.physics.add.group({
        key: 'particle',
        repeat: 49,
        setXY: { x: 100, y: 100, stepX: 14, stepY: 10 }
    });

    attractor = this.add.circle(400, 300, 10, 0xff0000);
}

Реализация аттрактора

Для каждого объекта из группы particles вычисляется вектор к аттрактору и применяется ускорение.

function update() {
    particles.children.iterate(function(particle) {
        let dx = attractor.x - particle.x;
        let dy = attractor.y - particle.y;
        let distance = Math.sqrt(dx*dx + dy*dy);

        if (distance > 0) {
            let force = 200 / distance; // сила уменьшается с расстоянием
            particle.body.velocity.x += (dx / distance) * force * 0.016;
            particle.body.velocity.y += (dy / distance) * force * 0.016;
        }
    });
}

Ключевые моменты:

  • dx / distance и dy / distance нормализуют вектор направления.
  • Умножение на force регулирует интенсивность притяжения.
  • Множитель 0.016 учитывает средний интервал обновления кадров (FPS).

Реализация отталкивателя

Принцип аналогичен, но сила меняет знак.

let repeller = this.add.circle(600, 300, 10, 0x0000ff);

particles.children.iterate(function(particle) {
    let dx = particle.x - repeller.x;
    let dy = particle.y - repeller.y;
    let distance = Math.sqrt(dx*dx + dy*dy);

    if (distance > 0) {
        let force = 150 / distance; // уменьшается с расстоянием
        particle.body.velocity.x += (dx / distance) * force * 0.016;
        particle.body.velocity.y += (dy / distance) * force * 0.016;
    }
});

Комбинирование аттракторов и отталкивателей

Можно использовать несколько источников сил одновременно, суммируя их векторы:

particles.children.iterate(function(particle) {
    let fx = 0;
    let fy = 0;

    // Притяжение
    let dx1 = attractor.x - particle.x;
    let dy1 = attractor.y - particle.y;
    let dist1 = Math.sqrt(dx1*dx1 + dy1*dy1);
    if (dist1 > 0) {
        let f1 = 200 / dist1;
        fx += (dx1 / dist1) * f1;
        fy += (dy1 / dist1) * f1;
    }

    // Отталкивание
    let dx2 = particle.x - repeller.x;
    let dy2 = particle.y - repeller.y;
    let dist2 = Math.sqrt(dx2*dx2 + dy2*dy2);
    if (dist2 > 0) {
        let f2 = 150 / dist2;
        fx += (dx2 / dist2) * f2;
        fy += (dy2 / dist2) * f2;
    }

    particle.body.velocity.x += fx * 0.016;
    particle.body.velocity.y += fy * 0.016;
});

Такой подход позволяет создавать динамические сцены с множеством источников силы, имитируя гравитационные поля или защитные зоны.


Оптимизация производительности

  • Использовать Phaser.Math.Distance.Between вместо ручного вычисления корня, если не требуется точная нормализация.
  • Ограничивать максимальную скорость объектов с помощью Phaser.Physics.Arcade.Body.maxVelocity.
  • Для большого числа частиц рассматривать Matter.js с встроенной поддержкой сил и коллизий.

Визуальные эффекты

  • Цветовая маркировка аттракторов и отталкивателей упрощает отладку.
  • Можно добавлять частицы с alpha и изменять размер при приближении к источнику силы.
  • Смешение притяжения и отталкивания позволяет создавать эффекты «торнадо», магнитного поля и симуляции планетарных систем.

Применение в играх

  • Игры с гравитационными платформами, где игрок притягивается к объектам.
  • Системы частиц для визуализации магии или взрывов.
  • Искусственный интеллект, где NPC избегают зон опасности или движутся к цели.

Использование аттракторов и отталкивателей в Phaser открывает возможности для сложной физики и интерактивной динамики без необходимости интеграции сторонних движков.