О чем этот пример
При работе с тайловыми картами иногда нужно изменить размер слоя уже после его создания — например, для реализации динамически генерируемых уровней или адаптации карты под игровой процесс. В этой статье мы разберем, как изменить ширину тайлового слоя в Phaser 3, просто присвоив новое значение свойству `width`, и как правильно настроить границы камеры для комфортного скроллинга. Этот подход особенно полезен при создании процедурно генерируемых миров или при динамическом добавлении новых областей на карту во время выполнения игры.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
controls;
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.tilemapTiledJSON('map', 'assets/tilemaps/maps/super-mario.json');
this.load.image('tiles', 'assets/tilemaps/tiles/super-mario.png');
}
create ()
{
const map = this.make.tilemap({ key: 'map' });
const tileset = map.addTilesetImage('SuperMarioBros-World1-1', 'tiles');
const layer = map.createLayer('World1', tileset, 100, 200);
// Map size
layer.width = 400;
const cursors = this.input.keyboard.createCursorKeys();
const controlConfig = {
camera: this.cameras.main,
left: cursors.left,
right: cursors.right,
speed: 0.5
};
this.controls = new Phaser.Cameras.Controls.FixedKeyControl(controlConfig);
this.cameras.main.setBounds(0, 0, layer.x + layer.width, 0);
}
update (time, delta)
{
this.controls.update(delta);
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
pixelArt: true,
scene: Example
};
const game = new Phaser.Game(config);
Загрузка и создание тайловой карты
В методе preload мы загружаем данные карты в формате JSON (созданной в Tiled) и изображение тайлсета. В методе create создаем саму карту, связываем тайлсет и создаем слой.
const map = this.make.tilemap({ key: 'map' });
const tileset = map.addTilesetImage('SuperMarioBros-World1-1', 'tiles');
const layer = map.createLayer('World1', tileset, 100, 200);
Обратите внимание на параметры 100, 200 в createLayer. Они задают смещение слоя от левого верхнего угла сцены. Это важно для последующей настройки камеры.
Изменение ширины слоя
Ключевой момент примера — изменение ширины уже созданного слоя. Это делается прямым присваиванием значения свойству width объекта слоя.
layer.width = 400;
После этой операции визуальная ширина слоя (то, сколько тайлов отрисовывается) изменится. Однако важно понимать, что это не меняет исходные данные карты (map), а лишь влияет на отображение конкретного слоя. Если в данных карты было, например, 30 столбцов тайлов, а мы задали ширину 400 пикселей, то будет отображено столько столбцов, сколько помещается в эти 400 пикселей, исходя из размера тайла.
Настройка управления камерой
Для демонстрации изменения размера карты в примере добавлено управление камерой с клавиатуры. Создаем объект управления FixedKeyControl.
const cursors = this.input.keyboard.createCursorKeys();
const controlConfig = {
camera: this.cameras.main,
left: cursors.left,
right: cursors.right,
speed: 0.5
};
this.controls = new Phaser.Cameras.Controls.FixedKeyControl(controlConfig);
Управление обновляется в методе update. Камера будет двигаться влево и вправо со скоростью 0.5.
Установка границ камеры
Чтобы камера скроллилась только в пределах видимой части слоя, необходимо задать границы камеры. Левая граница — 0. Правая граница рассчитывается как сумма смещения слоя по X (layer.x) и его новой ширины (layer.width).
this.cameras.main.setBounds(0, 0, layer.x + layer.width, 0);
Параметры setBounds — это `x,y,width,height. Мы устанавливаемwidthравнойlayer.x + layer.width, потому чтоlayer.x— это отступ слоя от левого края мира. Таким образом, правая граница мира для камеры будет находиться ровно на правом краю нашего слоя. Значенияyиheight` равны 0, так как вертикальный скроллинг в этом примере не предусмотрен.
Что попробовать дальше
Изменение свойства width у тайлового слоя — простой и эффективный способ динамически управлять размером игровой области. Это открывает возможности для создания уровней, которые расширяются по мере прохождения, или для подгрузки новых частей карты.
Для экспериментов попробуйте:
1. Менять ширину слоя в ответ на события игры (например, при достижении игроком определенной точки).
2. Реализовать плавное изменение ширины с помощью твинов для анимированного "роста" уровня.
3. Комбинировать изменение ширины с изменением высоты (layer.height), чтобы создавать динамические комнаты.
