Статические и динамические тела

В библиотеке Phaser реализовано несколько физических движков, среди которых наиболее часто используется Arcade Physics. Этот движок ориентирован на высокую производительность и простоту использования, что делает его оптимальным для 2D-игр с большим количеством объектов. Основой работы Arcade Physics являются физические тела (bodies), которые делятся на два ключевых типа:

  • Статические тела (Static Bodies)
  • Динамические тела (Dynamic Bodies)

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


Динамические тела

Общая характеристика

Динамическое тело — это физический объект, который:

  • реагирует на гравитацию,
  • изменяет скорость и ускорение,
  • участвует в столкновениях,
  • может быть перемещён силами или напрямую через скорость.

Создание динамического тела происходит через метод:

this.physics.add.sprite(x, y, 'texture');

Такой объект автоматически получает компонент body, который является экземпляром Phaser.Physics.Arcade.Body.


Основные свойства динамического тела

1. Скорость

player.body.velocity.x = 200;
player.body.velocity.y = -300;

Скорость определяет перемещение за кадр. Её изменение влияет на физическое поведение объекта.

2. Ускорение

player.body.acceleration.x = 50;

Используется для постепенного изменения скорости, например, при симуляции движения транспорта.

3. Гравитация

player.body.setGravityY(500);

Гравитация может быть глобальной или локальной для конкретного тела.

4. Отскок (Bounce)

player.setBounce(0.5);

Значение от 0 до 1 определяет коэффициент упругости.

5. Масса

player.body.setMass(2);

Масса влияет на результат столкновения двух динамических тел.


Участие в столкновениях

Динамические тела:

  • сталкиваются с другими динамическими телами,
  • сталкиваются со статическими телами,
  • могут вызывать события коллизии и перекрытия.

Пример:

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

В этом случае player — динамический объект, platforms — группа тел.


Особенности работы

  1. Позиция динамического тела управляется физическим движком.
  2. Прямое изменение x и y допустимо, но может привести к некорректным столкновениям.
  3. Производительность ниже, чем у статических тел, из-за расчёта скорости, ускорения и столкновений.

Статические тела

Общая характеристика

Статическое тело — это объект, который:

  • не реагирует на гравитацию,
  • не изменяет положение под действием сил,
  • используется как неподвижное препятствие.

Создание:

this.physics.add.staticSprite(x, y, 'platform');

Либо через группу:

this.physics.add.staticGroup();

Статические тела представлены классом Phaser.Physics.Arcade.StaticBody.


Ключевые свойства

  1. Отсутствие скорости и ускорения
  2. Игнорирование гравитации
  3. Отсутствие расчёта массы
  4. Высокая производительность

Статическое тело не пересчитывается каждый кадр, что делает его более эффективным при большом количестве объектов.


Перемещение статического тела

Хотя статическое тело считается неподвижным, его можно переместить вручную:

platform.x = 400;
platform.refreshBody();

Метод refreshBody() обязателен, поскольку физический движок не отслеживает изменения координат автоматически.

Без вызова refreshBody() столкновения будут происходить по старым координатам.


Сравнение статических и динамических тел

Характеристика Динамическое тело Статическое тело
Реагирует на гравитацию Да Нет
Имеет скорость Да Нет
Имеет ускорение Да Нет
Может двигаться Да Только вручную
Пересчёт каждый кадр Да Нет
Производительность Ниже Выше

Взаимодействие статических и динамических тел

Наиболее распространённая схема — динамический игрок и статические платформы.

const platforms = this.physics.add.staticGroup();
platforms.create(400, 568, 'ground');

const player = this.physics.add.sprite(100, 450, 'player');

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

В этом примере:

  • Платформы не двигаются.
  • Игрок падает под действием гравитации.
  • При столкновении движение по оси Y прекращается.

Физический движок рассчитывает только движение динамического объекта, что существенно экономит ресурсы.


Использование групп

Dynamic Group

const enemies = this.physics.add.group({
    velocityX: 100,
    bounceX: 1,
    collideWorldBounds: true
});

Все объекты в группе являются динамическими.


Static Group

const walls = this.physics.add.staticGroup();

Применяется для:

  • тайловых карт,
  • платформ,
  • стен,
  • декораций с коллизией.

Производительность и архитектурные решения

Когда использовать статические тела

  • Неподвижные платформы
  • Стены
  • Земля
  • Границы уровня
  • Препятствия

Использование динамического тела для неподвижного объекта приводит к лишним вычислениям.


Когда использовать динамические тела

  • Игрок
  • Противники
  • Пули
  • Подвижные платформы
  • Предметы, падающие под действием гравитации

Частые ошибки

1. Использование динамического тела для платформ

Это создаёт ненужную нагрузку и может вызвать нестабильность.

2. Перемещение статического тела без refreshBody()

platform.x += 100;

Без:

platform.refreshBody();

Физика будет работать некорректно.

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

player.x += 10;

Предпочтительнее использовать:

player.setVelocityX(200);

Иначе возможно «проталкивание» сквозь объекты.


Глубокие технические различия

Обновление в игровом цикле

Динамическое тело проходит этапы:

  1. Применение ускорения
  2. Применение гравитации
  3. Расчёт скорости
  4. Проверка столкновений
  5. Коррекция позиции

Статическое тело:

  • участвует только в фазе проверки столкновений,
  • не обновляет скорость,
  • не изменяет координаты автоматически.

Коллизии между статическими телами

Статические тела не сталкиваются друг с другом. Проверка происходит только при взаимодействии с динамическими телами.


Статическое тело как оптимизация тайловых карт

При работе с Tilemap слои можно преобразовать в статические тела:

layer.setCollisionByProperty({ collides: true });
this.physics.add.collider(player, layer);

В этом случае коллизия создаётся на основе данных карты, а слой рассматривается как набор статических тел.


Динамические тела с immovable

Иногда требуется объект, который не двигается при столкновении, но остаётся динамическим:

platform.body.setImmovable(true);

Такой объект:

  • остаётся динамическим,
  • может двигаться программно,
  • не будет смещаться при столкновении.

Это промежуточный вариант между статическим и динамическим телом.


Отладка физических тел

Для визуализации тел используется режим debug:

physics: {
    default: 'arcade',
    arcade: {
        debug: true
    }
}

Отображаются:

  • границы тела,
  • точки касания,
  • направления скорости.

Отладка особенно важна при различиях размеров спрайта и его физического тела.


Изменение размеров тела

По умолчанию физическое тело совпадает с размером текстуры. Изменение:

player.body.setSize(32, 48);
player.body.setOffset(10, 5);

Актуально для:

  • точной настройки хитбоксов,
  • персонажей с прозрачными областями,
  • оптимизации коллизий.

Архитектурные рекомендации

  1. Максимально использовать статические тела для окружения.
  2. Минимизировать количество динамических объектов.
  3. Избегать ручного изменения координат динамических тел.
  4. Разделять логику движения и физику.
  5. Использовать immovable для движущихся платформ.

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