О чем этот пример
Физический движок Phaser позволяет объектам взаимодействовать с границами игрового мира, но что если нужно не просто отскочить, а выполнить какое-то действие в момент касания? Например, изменить направление стрелки или запустить звуковой эффект. В этом примере мы используем событие `worldbounds` для мгновенной реакции на столкновение спрайта с любой из четырех границ сцены. Это полезно для создания точных игровых механик, где важно именно место столкновения, а не сам факт отскока.
Версия 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('bg', 'assets/skies/space2.png');
this.load.image('arrow', 'assets/sprites/arrow.png');
}
create ()
{
this.add.image(400, 300, 'bg');
this.physics.add.sprite(200, 150, 'arrow')
.setVelocity(200, -200)
.setCollideWorldBounds(true, 1, 1, true);
this.physics.world.on('worldbounds', (body, up, down, left, right) =>
{
const { gameObject } = body;
if (up) { gameObject.setAngle(90); }
else if (down) { gameObject.setAngle(-90); }
else if (left) { gameObject.setAngle(0); }
else if (right) { gameObject.setAngle(180); }
});
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
pixelArt: true,
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
debug: false
}
},
scene: Example
};
const game = new Phaser.Game(config);
Настройка физического спрайта
Ключевой момент — создание физического спрайта с включенной опцией setCollideWorldBounds. Последний, четвертый аргумент этого метода (true) включает генерацию события при столкновении с границей. Без него спрайт просто отскочит, но событие worldbounds не будет сгенерировано.
this.physics.add.sprite(200, 150, 'arrow')
.setVelocity(200, -200)
.setCollideWorldBounds(true, 1, 1, true);
Здесь мы создаем спрайт стрелки, задаем ему начальную скорость и говорим движку: "столкновение с границами мира включено, коэффициент восстановления по осям X и Y равен 1 (упругий отскок), и при столкновении генерируй событие".
Подписка на событие 'worldbounds'
Событие worldbounds генерируется объектом this.physics.world, который представляет собой мир физического движка Arcade. На это событие нужно подписаться, передав функцию-обработчик (callback).
this.physics.world.on('worldbounds', (body, up, down, left, right) =>
{
// Логика обработки
});
В обработчик передается несколько аргументов: body — физическое тело объекта, столкнувшегося с границей, и четыре булевых флага (up, down, left, right). Эти флаги точно указывают, с какой именно границей произошло столкновение.
Логика реакции на столкновение
Внутри обработчика мы деструктурируем gameObject из переданного тела body. Это сам спрайт, связанный с физическим телом. Затем, проверяя флаги, мы меняем угол поворота этого спрайта (setAngle), чтобы стрелка всегда "смотрела" от границы, которую она только что задела.
const { gameObject } = body;
if (up) { gameObject.setAngle(90); }
else if (down) { gameObject.setAngle(-90); }
else if (left) { gameObject.setAngle(0); }
else if (right) { gameObject.setAngle(180); }
Например, если сработал флаг up (столкновение с верхней границей), устанавливаем угол 90 градусов, и стрелка смотрит вниз.
Настройка конфигурации игры
Для работы примера необходима правильная конфигурация игры, в которой активирован физический движок Arcade.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
pixelArt: true,
parent: 'phaser-example',
physics: {
default: 'arcade', // Используем Arcade Physics
arcade: {
debug: false // Отключаем отладочную визуализацию
}
},
scene: Example
};
Важно убедиться, что в объекте physics указан default: 'arcade'. Параметры width и height определяют размеры мира, границы которого (world bounds) будут проверяться.
Что попробовать дальше
Событие worldbounds — это мощный инструмент для создания детализированной обратной связи в игре. Оно позволяет реагировать не просто на факт отскока от края, а на конкретную сторону столкновения. Попробуйте расширить пример: добавляйте звуковые эффекты с помощью this.sound.play, создавайте частицы через this.add.particles при ударе или меняйте скорость объекта в зависимости от задетой границы.
