В библиотеке Phaser реализовано несколько физических движков, среди которых наиболее часто используется Arcade Physics. Этот движок ориентирован на высокую производительность и простоту использования, что делает его оптимальным для 2D-игр с большим количеством объектов. Основой работы Arcade Physics являются физические тела (bodies), которые делятся на два ключевых типа:
Понимание различий между ними критично для корректного проектирования игровой механики, оптимизации производительности и построения системы столкновений.
Динамическое тело — это физический объект, который:
Создание динамического тела происходит через метод:
this.physics.add.sprite(x, y, 'texture');
Такой объект автоматически получает компонент body,
который является экземпляром
Phaser.Physics.Arcade.Body.
player.body.velocity.x = 200;
player.body.velocity.y = -300;
Скорость определяет перемещение за кадр. Её изменение влияет на физическое поведение объекта.
player.body.acceleration.x = 50;
Используется для постепенного изменения скорости, например, при симуляции движения транспорта.
player.body.setGravityY(500);
Гравитация может быть глобальной или локальной для конкретного тела.
player.setBounce(0.5);
Значение от 0 до 1 определяет коэффициент упругости.
player.body.setMass(2);
Масса влияет на результат столкновения двух динамических тел.
Динамические тела:
Пример:
this.physics.add.collider(player, platforms);
В этом случае player — динамический объект,
platforms — группа тел.
x и y допустимо, но может
привести к некорректным столкновениям.Статическое тело — это объект, который:
Создание:
this.physics.add.staticSprite(x, y, 'platform');
Либо через группу:
this.physics.add.staticGroup();
Статические тела представлены классом
Phaser.Physics.Arcade.StaticBody.
Статическое тело не пересчитывается каждый кадр, что делает его более эффективным при большом количестве объектов.
Хотя статическое тело считается неподвижным, его можно переместить вручную:
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);
В этом примере:
Физический движок рассчитывает только движение динамического объекта, что существенно экономит ресурсы.
const enemies = this.physics.add.group({
velocityX: 100,
bounceX: 1,
collideWorldBounds: true
});
Все объекты в группе являются динамическими.
const walls = this.physics.add.staticGroup();
Применяется для:
Использование динамического тела для неподвижного объекта приводит к лишним вычислениям.
Это создаёт ненужную нагрузку и может вызвать нестабильность.
platform.x += 100;
Без:
platform.refreshBody();
Физика будет работать некорректно.
player.x += 10;
Предпочтительнее использовать:
player.setVelocityX(200);
Иначе возможно «проталкивание» сквозь объекты.
Динамическое тело проходит этапы:
Статическое тело:
Статические тела не сталкиваются друг с другом. Проверка происходит только при взаимодействии с динамическими телами.
При работе с Tilemap слои можно преобразовать в статические тела:
layer.setCollisionByProperty({ collides: true });
this.physics.add.collider(player, layer);
В этом случае коллизия создаётся на основе данных карты, а слой рассматривается как набор статических тел.
Иногда требуется объект, который не двигается при столкновении, но остаётся динамическим:
platform.body.setImmovable(true);
Такой объект:
Это промежуточный вариант между статическим и динамическим телом.
Для визуализации тел используется режим debug:
physics: {
default: 'arcade',
arcade: {
debug: true
}
}
Отображаются:
Отладка особенно важна при различиях размеров спрайта и его физического тела.
По умолчанию физическое тело совпадает с размером текстуры. Изменение:
player.body.setSize(32, 48);
player.body.setOffset(10, 5);
Актуально для:
immovable для движущихся платформ.Корректное понимание различий между статическими и динамическими телами позволяет создавать стабильную, производительную и предсказуемую физическую систему в играх на базе Phaser.