О чем этот пример
В разработке игр реалистичное движение объектов — ключ к созданию приятной игровой механики. Пример демонстрирует, как использовать демпфирование (damping) и сопротивление (drag) в физическом движке Arcade для создания инерционного, плавно замедляющегося движения спрайтов, сталкивающихся друг с другом и с границами мира. Это особенно полезно для симуляции движения в среде с 'сопротивлением', например, под водой или в космосе с разреженной средой.
Версия 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('block', 'assets/sprites/block.png');
}
create ()
{
const group = this.physics.add.group({
bounceX: 0.5,
bounceY: 0.5,
collideWorldBounds: true,
dragX: 0.5,
dragY: 0.5
});
group.create(100, 200, 'block').setVelocity(100, 200).setDamping(true);
group.create(500, 200, 'block').setVelocity(-100, -100).setDamping(true);
group.create(300, 400, 'block').setVelocity(60, 100).setDamping(true);
group.create(600, 300, 'block').setVelocity(-30, -50).setDamping(true);
this.physics.add.collider(group);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
debug: true,
gravity: { y: 200 }
}
},
scene: Example
};
const game = new Phaser.Game(config);
Настройка физической группы
Вместо того чтобы настраивать свойства каждого физического спрайта по отдельности, Phaser позволяет создавать группы (Group) с общими физическими параметрами. Это эффективно и удобно для управления множеством однотипных объектов.
В методе create() создаётся физическая группа с помощью this.physics.add.group(). Конфигурационный объект задаёт глобальные свойства для всех её членов:
const group = this.physics.add.group({
bounceX: 0.5,
bounceY: 0.5,
collideWorldBounds: true,
dragX: 0.5,
dragY: 0.5
});
* bounceX и bounceY: Определяют упругость (коэффициент восстановления) при столкновениях. Значение 0.5 означает, что объект сохранит 50% своей скорости после отскока.
* collideWorldBounds: Булев флаг, разрешающий объектам группы сталкиваться с границами игрового мира.
* dragX и dragY: Задают линейное сопротивление (drag) по осям. Это постоянная сила, замедляющая движение. Значение 0.5 обеспечивает заметное, но не мгновенное замедление.
Создание спрайтов и включение демпфирования
Спрайты добавляются в группу методом group.create(), который автоматически наделяет их физическим телом (Body) с настройками, унаследованными от группы.
group.create(100, 200, 'block').setVelocity(100, 200).setDamping(true);
group.create(500, 200, 'block').setVelocity(-100, -100).setDamping(true);
// ... и другие спрайты
Каждому спрайту сразу после создания задаётся начальная скорость с помощью .setVelocity(x, y). Затем для него вызывается .setDamping(true). **Демпфирование (damping)** — это ключевой момент примера. В отличие от линейного сопротивления (drag), которое действует как постоянная тормозящая сила, демпфирование обеспечивает экспоненциальное замедление. Чем выше текущая скорость объекта, тем сильнее сила замедления. Это создаёт более натуральное, инерционное ощущение движения, как у массивного объекта, постепенно теряющего скорость.
Организация столкновений
Чтобы спрайты в группе могли сталкиваться друг с другом, необходимо создать коллайдер (collider). Самый простой способ — использовать this.physics.add.collider() и передать одну и ту же группу в оба аргумента.
this.physics.add.collider(group);
Эта строка эквивалентна this.physics.add.collider(group, group). Она регистрирует проверку столкновений между всеми телами внутри группы. В сочетании с включённым collideWorldBounds это означает, что блоки будут отскакивать как от границ экрана, так и друг от друга, используя заданные коэффициенты упругости (bounce).
Конфигурация игры и движка Arcade
Глобальная конфигурация игры (config) определяет, какой физический движок используется и как он настроен.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade', // Используется движок Arcade Physics
arcade: {
debug: true, // Включает отладочную отрисовку хитбоксов
gravity: { y: 200 } // Гравитация, направленная вниз
}
},
scene: Example
};
* debug: true — очень полезная опция при отладке. Она визуализирует физические тела (обычно прямоугольники), позволяя точно видеть, как движок воспринимает столкновения.
* gravity: { y: 200 } — задаёт постоянное ускорение вниз по оси Y. В этом примере оно сочетается с демпфированием и сопротивлением, заставляя блоки в итоге падать и скапливаться внизу сцены, постепенно теряя энергию отскоков.
Что попробовать дальше
Комбинация setDamping(true), линейного сопротивления (drag) и гравитации создаёт сложное и реалистичное поведение физических тел. Для экспериментов попробуйте: отключить демпфирование и оставить только drag, чтобы почувствовать разницу; изменить коэффициенты bounce на 1.0 для абсолютно упругих столкновений или на 0.0 для полностью неупругих; увеличить гравитацию или вовсе убрать её, чтобы наблюдать за движением в невесомости. Эти параметры — мощные инструменты для тонкой настройки 'ощущений' от игры.
