О чем этот пример
В играх объекты редко двигаются в идеальном вакууме. Часто их движение должно замедляться из-за трения или сопротивления среды. Встроенный физический движок Arcade в Phaser позволяет легко добавить такое сопротивление по осям X и Y, делая поведение объектов более реалистичным и управляемым. В этой статье мы разберем, как настроить сопротивление (`drag`) для группы физических тел, чтобы они не скользили вечно по экрану.
Версия 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: 100,
dragY: 100
});
group.create(100, 200, 'block').setVelocity(100, 200);
group.create(500, 200, 'block').setVelocity(-100, -100);
group.create(300, 400, 'block').setVelocity(60, 100);
group.create(600, 300, 'block').setVelocity(-30, -50);
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);
Настройка физического мира и загрузка ассетов
Первым делом в методе preload мы загружаем спрайт, который будет использоваться в качестве физического тела. Важно установить базовый URL для загрузчика, чтобы корректно найти ресурсы.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('block', 'assets/sprites/block.png');
}
Конфигурация игры определяет, что мы используем физический движок Arcade. Включен режим отладки (debug: true), который рисует хитбоксы, и задана гравитация по оси Y (gravity: { y: 200 }), которая будет тянуть объекты вниз.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
debug: true,
gravity: { y: 200 }
}
},
scene: Example
};
Создание группы с общими физическими свойствами
В методе create мы создаем физическую группу объектов с помощью this.physics.add.group. Группа — это удобный способ управлять множеством объектов с одинаковыми свойствами.
Ключевые параметры конфигурации группы:
* bounceX, bounceY: Коэффициент упругости (от 0 до 1) при столкновениях.
* collideWorldBounds: Разрешает объектам сталкиваться с границами мира (экрана).
* dragX, dragY: **Сопротивление движению** по соответствующим осям. Чем выше значение, тем быстрее объект будет терять скорость. В нашем примере установлено значение 100 для обеих осей.
const group = this.physics.add.group({
bounceX: 0.5,
bounceY: 0.5,
collideWorldBounds: true,
dragX: 100,
dragY: 100
});
Добавление объектов в группу и настройка коллизий
После создания группы мы добавляем в нее отдельные спрайты с помощью метода group.create. Каждому спрайту сразу задается начальная позиция и, что важно, начальная скорость с помощью setVelocity. Благодаря свойствам группы, все созданные спрайты автоматически получают физическое тело с заданным сопротивлением, упругостью и будут взаимодействовать с границами мира.
group.create(100, 200, 'block').setVelocity(100, 200);
group.create(500, 200, 'block').setVelocity(-100, -100);
group.create(300, 400, 'block').setVelocity(60, 100);
group.create(600, 300, 'block').setVelocity(-30, -50);
Затем мы настраиваем коллизии между всеми объектами внутри одной группы. Вызов this.physics.add.collider(group) заставляет объекты группы сталкиваться друг с другом, отталкиваясь согласно заданным параметрам bounce.
this.physics.add.collider(group);
Как работает сопротивление (Drag) на практике
Без параметров dragX и dragY объекты под действием гравитации и начальной скорости двигались бы практически бесконечно, лишь отскакивая от стен и друг от друга. Сопротивление имитирует силу трения.
1. **Начало движения:** Объект получает начальный импульс от setVelocity.
2. **Влияние гравитации:** Сила тяжести постоянно добавляет ускорение вниз.
3. **Действие сопротивления:** Каждый кадр физический движок Arcade уменьшает скорость объекта на значение drag (100 единиц в секунду), но не ниже нуля. Это приводит к плавному, а не мгновенному, замедлению.
4. **Результат:** Объекты постепенно теряют скорость, их движение становится более "тяжелым" и реалистичным. В сочетании с гравитацией и отскоками это создает интересную физическую симуляцию.
Сопротивление можно настраивать индивидуально для каждого объекта после его создания, изменяя свойства body.drag.x и body.drag.y.
Что попробовать дальше
Использование dragX и dragY в Arcade Physics — это простой, но мощный способ контролировать инерцию объектов. Это основа для создания ощущения движения по песку, воде, льду или просто для предотвращения бесконечного скольжения.
**Идеи для экспериментов:**
* Создайте разные группы с разными значениями сопротивления (например, 10, 50, 200) и понаблюдайте за разницей в поведении.
* Попробуйте асимметричные значения, например dragX: 200, dragY: 20, чтобы смоделировать движение в вязкой горизонтальной среде.
* Динамически меняйте body.drag объекта при определенных событиях (например, когда герой заходит в воду).
