О чем этот пример
Режим масштабирования `Phaser.Scale.NONE` отключает автоматическое управление размерами игры, передавая полный контроль разработчику. Это полезно для нестандартных встраиваний, сложных адаптивных интерфейсов или интеграции с другими системами, где нужно тонко реагировать на каждое изменение окна. В этой статье мы разберем, как вручную обрабатывать событие ресайза, чтобы ваша игра корректно отображалась при любом размере окна.
Версия 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('rain', 'assets/pics/thalion-rain.png');
this.load.image('logo', 'assets/sprites/phaser3-logo-x2.png');
}
create ()
{
const bg = this.add.tileSprite(0, 0, this.scale.width, this.scale.height, 'rain').setOrigin(0);
const logo = this.add.sprite(this.scale.width / 2, this.scale.height / 2, 'logo').setInteractive();
logo.on('pointerover', function ()
{
this.setTint(0xff0000);
});
logo.on('pointerout', function ()
{
this.clearTint();
});
this.scale.on('resize', function (gameSize)
{
const width = gameSize.width;
const height = gameSize.height;
this.cameras.resize(width, height);
bg.setSize(width, height);
logo.setPosition(width / 2, height / 2);
}, this);
}
}
const config = {
type: Phaser.WEBGL,
backgroundColor: '#2dab2d',
scale: {
mode: Phaser.Scale.NONE,
parent: 'phaser-example',
width: window.innerWidth,
height: window.innerHeight
},
scene: Example
};
const game = new Phaser.Game(config);
// In scaleMode NONE the Scale Manager is effectively disabled, so you need to
// tell it when a resize happens yourself:
window.addEventListener('resize', event =>
{
game.scale.resize(window.innerWidth, window.innerHeight);
}, false);
Настройка конфигурации: отключаем автомасштабирование
Ключевой момент – правильная настройка объекта scale в конфигурации игры. Установка mode: Phaser.Scale.NONE говорит Phaser не предпринимать никаких автоматических действий при изменении размеров окна браузера. Родительский контейнер и стартовые размеры задаются явно.
const config = {
type: Phaser.WEBGL,
scale: {
mode: Phaser.Scale.NONE, // Автомасштабирование отключено
parent: 'phaser-example',
width: window.innerWidth, // Стартовая ширина
height: window.innerHeight // Стартовая высота
},
scene: Example
};
Перехват события ресайза окна браузера
Поскольку Scale Manager отключен, он не слушает события resize у окна. Эту обязанность берёт на себя разработчик. Мы создаём слушатель на глобальном объекте window, который при каждом изменении размеров окна будет вызывать метод game.scale.resize() с новыми значениями. Именно этот вызов инициирует внутреннюю логику ресайза в Phaser.
window.addEventListener('resize', event => {
game.scale.resize(window.innerWidth, window.innerHeight);
}, false);
Реакция на ресайз внутри сцены
Вызов game.scale.resize() генерирует событие 'resize' у менеджера масштабирования самой игры. На это событие мы можем подписаться внутри сцены. Обработчик получает объект gameSize с актуальными шириной и высотой. Здесь выполняется основная работа по адаптации игрового контента.
this.scale.on('resize', function (gameSize) {
const width = gameSize.width;
const height = gameSize.height;
// Логика адаптации
}, this);
Адаптация игровых объектов под новый размер
В обработчике события необходимо обновить все объекты, зависящие от размеров экрана. Во-первых, нужно перенастроить камеру через this.cameras.resize(). Во-вторых, изменить размеры и позиции спрайтов. TileSprite обновляется методом setSize(), а обычный спрайт перепозиционируется методом setPosition().
// 1. Ресайз камеры под новый размер области отрисовки
this.cameras.resize(width, height);
// 2. Обновление размера фонового TileSprite
bg.setSize(width, height);
// 3. Перемещение основного спрайта в новый центр
logo.setPosition(width / 2, height / 2);
Что попробовать дальше
Ручное управление ресайзом через Phaser.Scale.NONE даёт полную свободу, но требует внимательности: не забудьте подписаться на событие окна и обновить все зависимые объекты. Для экспериментов попробуйте анимировать изменение размеров, добавить debounce на вызов resize для производительности или реализовать сложную логику адаптации UI для разных соотношений сторон.
