О чем этот пример
При создании игр часто возникает необходимость в более точных коллизиях, чем границы спрайта. Например, персонаж с широкой анимацией или объект с "мертвыми зонами". Phaser 3 Arcade Physics позволяет легко задавать пользовательские прямоугольники столкновений (bounding box), которые могут быть меньше или больше визуального спрайта. В этой статье разберем, как использовать метод `setSize()` для создания точных физических взаимодействий.
Версия 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('atari', 'assets/sprites/atari130xe.png');
this.load.image('mushroom', 'assets/sprites/mushroom2.png');
}
create ()
{
const atari = this.physics.add.image(200, 400, 'atari').setImmovable(true);
// In this example the new collision box is smaller than the original sprite
// 220x104 original size, 110x52 new size, the 'true' argument means "center it on the gameobject"
atari.setSize(110, 52, true);
// And this sprite will collide with it
const mushroom1 = this.physics.add.image(700, 350, 'mushroom');
const mushroom2 = this.physics.add.image(200, 50, 'mushroom');
mushroom1.setVelocity(-100, 0);
mushroom2.setVelocity(0, 100);
this.physics.add.collider(atari, [ mushroom1, mushroom2 ]);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
debug: true
}
},
scene: Example
};
const game = new Phaser.Game(config);
Зачем менять размер коллайдера?
По умолчанию физическое тело (body) в Arcade Physics создается по размеру текстуры спрайта. Это не всегда соответствует игровому замыслу. Визуальные "крылья" самолета, аура вокруг магического шара или просто желание сделать столкновения более "человечными" для персонажа — все это требует настройки хитбокса.
Метод setSize() класса Arcade Physics Body позволяет переопределить размер и положение прямоугольника столкновений, не затрагивая отрисовку спрайта. В примере мы уменьшаем хитбокс компьютера Atari, чтобы грибы сталкивались именно с его корпусом, а не с краями спрайта.
Разбор кода: создание сцены и спрайтов
В методе preload() загружаются две текстуры. В create() создаются физические спрайты. Ключевой объект — atari — помечается как неподвижный (setImmovable(true)), что означает, что при столкновении его не будет сдвигать.
const atari = this.physics.add.image(200, 400, 'atari').setImmovable(true);
const mushroom1 = this.physics.add.image(700, 350, 'mushroom');
const mushroom2 = this.physics.add.image(200, 50, 'mushroom');
Грибам задается начальная скорость с помощью setVelocity. Столкновение между Atari и массивом грибов регистрируется через this.physics.add.collider.
Волшебный метод `setSize()`
Вот где происходит магия. Исходный спрайт atari имеет размер 220x104 пикселя. Мы задаем новый размер коллайдера — 110x52.
atari.setSize(110, 52, true);
Третий аргумент (center) — булево значение. Если true, новый прямоугольник столкновений будет отцентрирован относительно исходной позиции тела. Если false, его верхний левый угол совпадет с верхним левым углом исходного тела. В нашем случае центрирование позволяет уменьшить хитбокс равномерно со всех сторон.
**Важно:** setSize() — это метод тела (Body), но он вызывается от спрайта, так как в Arcade Physics спрайт является прокси для своего физического тела.
Визуализация и отладка
Чтобы увидеть, что именно происходит, в конфигурации физики включен режим отладки:
physics: {
default: 'arcade',
arcade: {
debug: true
}
}
При debug: true поверх спрайтов отрисовываются контуры их физических тел. Вы увидите, что зеленый контур (коллайдер) у atari теперь в два раза меньше красного контура спрайта. Это незаменимый инструмент для тонкой настройки столкновений.
Практическое применение и нюансы
1. **Смещение (setOffset):** Вместе с setSize() часто используют body.setOffset(x, y) для смещения коллайдера относительно спрайта. Например, для создания хитбокса только для верхней части объекта.
2. **Круглые коллайдеры:** Для более органичных столкновений используйте setCircle(radius) или setCircle(radius, offsetX, offsetY), чтобы задать тело в форме круга.
3. **Производительность:** Работа с прямоугольными (setSize) и круглыми телами в Arcade Physics очень эффективна. Избегайте создания множества мелких тел для одного спрайта — один измененный коллайдер почти всегда лучше.
Помните, что setSize влияет только на обнаружение столкновений. Методы для получения границ спрайта, например getBounds, по-прежнему возвращают исходные размеры текстуры.
Что попробовать дальше
Использование setSize() — это простой и мощный способ сделать физику вашей игры точной и правдоподобной. Поэкспериментируйте: создайте персонажа, у которого коллайдер меньше роста (чтобы предметы падали "перед ним"), или платформу, хитбокс которой меньше визуала, чтобы создавать иллюзию возможности зацепиться за край. Сочетание setSize и setOffset откроет полный контроль над игровыми взаимодействиями.
