О чем этот пример
Обработка смены ориентации устройства — ключевая задача для мобильных игр. Неправильная реакция на поворот экрана может испортить пользовательский опыт, особенно на iOS, где поведение браузера имеет свои особенности. Рассмотрим, как использовать Scale Manager в Phaser для точного определения ориентации и адаптации игрового процесса под текущее положение устройства. Эта техника полезна не только для корректного отображения интерфейса, но и для реализации геймплея, завязанного на ориентацию (например, в головоломках или аркадах), и для сбора аналитики о том, как пользователи предпочитают играть.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor()
{
super();
}
preload ()
{
// this.load.setBaseURL('https://cdn.phaserfiles.com/v385');
}
create ()
{
var print = this.add.text(0, 0, '');
this.scale.on('orientationchange', function (orientation)
{
var s = [ orientation ];
if (orientation === Phaser.Scale.PORTRAIT)
{
s.push('PORTRAIT PRIMARY')
}
else if (orientation === Phaser.Scale.PORTRAIT_SECONDARY)
{
s.push('PORTRAIT SECONDARY')
}
else if (orientation === Phaser.Scale.LANDSCAPE)
{
s.push('LANDSCAPE PRIMARY')
}
else if (orientation === Phaser.Scale.LANDSCAPE_SECONDARY)
{
s.push('LANDSCAPE SECONDARY')
} else
{
s.push('??')
}
print.text = s.join('\n')
});
print.text = this.scale.orientation;
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Настройка Scale Manager: Основа работы
Вся магия отслеживания ориентации начинается с правильной конфигурации игры. Ключевым объектом здесь является config, который передается в конструктор Phaser.Game. Хотя в примере явно не заданы настройки масштабирования, Phaser по умолчанию создает Scale Manager, который отслеживает изменения состояния окна браузера, включая ориентацию.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'phaser-example',
scene: Example
};
Важно помнить, что для мобильных устройств часто требуется дополнительная настройка масштабирования (например, использование scale.mode: Phaser.Scale.FIT), чтобы игра занимала весь экран. В данном же примере фокус сделан именно на событии смены ориентации.
Событие orientationchange: Ловим поворот
Ядро логики находится в методе create сцены. Мы подписываемся на событие 'orientationchange' объекта this.scale. Это событие генерируется Scale Manager каждый раз, когда система браузера определяет изменение ориентации устройства.
this.scale.on('orientationchange', function (orientation) {
// Обработчик события
});
Обработчик получает один аргумент — orientation. Это числовая константа, которую Phaser получает от браузера. Не стоит путать это событие с нативным JavaScript-событием window.orientationchange — Phaser абстрагирует эту логику и предоставляет унифицированный API.
Определяем тип ориентации: Декодируем константы
Phaser определяет четыре основные ориентации через константы объекта Phaser.Scale. Значение аргумента orientation нужно сравнивать с этими константами, чтобы понять, в какой именно режим перешел экран.
if (orientation === Phaser.Scale.PORTRAIT) {
s.push('PORTRAIT PRIMARY')
}
else if (orientation === Phaser.Scale.PORTRAIT_SECONDARY) {
s.push('PORTRAIT SECONDARY')
}
else if (orientation === Phaser.Scale.LANDSCAPE) {
s.push('LANDSCAPE PRIMARY')
}
else if (orientation === Phaser.Scale.LANDSCAPE_SECONDARY) {
s.push('LANDSCAPE SECONDARY')
} else {
s.push('??')
}
* PORTRAIT и LANDSCAPE — это основные (primary) ориентации (когда устройство повернуто «естественным» образом).
* PORTRAIT_SECONDARY и LANDSCAPE_SECONDARY — обратные (secondary) ориентации (устройство перевернуто).
Такой подход позволяет точно реагировать не просто на «альбомный» или «книжный» режим, а на конкретный разворот устройства, что может быть критично для игр с управлением акселерометром.
Отображение состояния: Текстовый вывод
Для демонстрации результата в примере используется текстовый объект. При старте сцены мы сразу выводим текущую ориентацию, доступную через свойство this.scale.orientation.
print.text = this.scale.orientation;
Затем, внутри обработчика события, мы формируем строку из числового кода ориентации и его текстовой расшифровки и обновляем тот же текстовый объект.
print.text = s.join('\n')
Такой подход полезен для отладки. В реальном проекте вместо вывода текста вы, скорее всего, будете вызывать метод ремасштабирования игрового мира, перераспределения элементов UI или изменения логики управления.
Что попробовать дальше
Использование события orientationchange от Scale Manager — это надежный и кроссплатформенный способ сделать вашу игру на Phaser отзывчивой к поворотам экрана. Он избавляет от необходимости работать напрямую с сырыми API браузера, которые могут отличаться на iOS и Android.
Для экспериментов попробуйте:
1. Связать смену ориентации с переключением между двумя разными игровыми сценами или режимами камеры.
2. Динамически менять расположение элементов управления (например, джойстика) в зависимости от того, в какой руке пользователь держит устройство (определяется по PRIMARY/SECONDARY).
3. Реализовать «жесткую» блокировку игры в одной ориентации, но с возможностью ручного переворота через системную кнопку, обрабатывая это событие.
