О чем этот пример
Часто размер вашего игрового мира превышает размер экрана игрока. Простая камера, которая следует за персонажем, в таких случаях не подходит — она упрётся в края сцены, и игрок не увидит всего контента. Решение — установить границы для камеры, которые позволят ей свободно перемещаться по всей площади вашего уровня. Эта статья на примере кода из официальных примеров Phaser покажет, как задать границы (`bounds`) для основной камеры и реализовать плавное управление её движением с клавиатуры. Этот подход незаменим для создания карт, больших платформеров или интерактивных панорам.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
constructor ()
{
super();
}
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('pic', 'assets/pics/the-end-by-iloe-and-made.jpg');
}
create ()
{
this.add.image(0, 0, 'pic').setOrigin(0);
// Set the camera bounds to be the size of the image
this.cameras.main.setBounds(0, 0, 1920, 1080);
// Camera controls
const cursors = this.input.keyboard.createCursorKeys();
const controlConfig = {
camera: this.cameras.main,
left: cursors.left,
right: cursors.right,
up: cursors.up,
down: cursors.down,
acceleration: 0.06,
drag: 0.0005,
maxSpeed: 1.0
};
this.controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
}
update (time, delta)
{
this.controls.update(delta);
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
backgroundColor: '#000000',
scene: Example
};
const game = new Phaser.Game(config);
Загрузка и отрисовка большого изображения
Основой нашего примера служит большое фоновое изображение. Его размер (1920x1080) значительно превосходит размер игрового холста (800x600).
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('pic', 'assets/pics/the-end-by-iloe-and-made.jpg');
}
В методе create изображение добавляется в точку (0, 0) с установленным setOrigin(0). Это означает, что его левый верхний угол совпадает с началом координат мира (0, 0).
this.add.image(0, 0, 'pic').setOrigin(0);
Без установки границ камеры мы увидим только левый верхний фрагмент этой картины размером 800x600 пикселей.
Установка границ для камеры
Ключевой метод для решения проблемы — this.cameras.main.setBounds(). Он сообщает камере, в каких пределах мировых координат она может перемещаться.
this.cameras.main.setBounds(0, 0, 1920, 1080);
Метод принимает четыре аргумента: `x,y(координаты левого верхнего угла области) иwidth,height` (размеры области). После этого вызова камера понимает, что её "вселенная" ограничена прямоугольником от (0,0) до (1920,1080). Она сможет перемещаться в этих границах, показывая игроку разные части изображения. Важно: эти координаты относятся к миру игры, а не к экрану.
Настройка плавного управления камерой
Чтобы продемонстрировать работу камеры в границах, добавим управление. Сначала создаём объект с кодами клавиш-стрелок.
const cursors = this.input.keyboard.createCursorKeys();
Затем настраиваем конфигурацию для специального контроллера Phaser.Cameras.Controls.SmoothedKeyControl. Этот контроллер обеспечивает инерционное, плавное движение камеры с ускорением и замедлением.
const controlConfig = {
camera: this.cameras.main, // Указываем, какой камерой управляем
left: cursors.left,
right: cursors.right,
up: cursors.up,
down: cursors.down, // Привязка клавиш к направлениям
acceleration: 0.06, // Скорость разгона
drag: 0.0005, // Сила "трения", замедляющая камеру
maxSpeed: 1.0 // Максимальная скорость перемещения
};
this.controls = new Phaser.Cameras.Controls.SmoothedKeyControl(controlConfig);
Контроллер создан, но для работы ему требуется обновление в каждом кадре.
Обновление состояния контроллера
Логика плавного перемещения и инерции рассчитывается внутри контроллера. Наша задача — вызывать его метод update в основном игровом цикле, передавая delta время (разницу в миллисекундах с предыдущим кадром). Это обеспечивает независимость скорости движения от частоты кадров.
update (time, delta)
{
this.controls.update(delta);
}
Без этого вызова нажатия на клавиши не будут иметь эффекта.
Итоговая конфигурация игры задаёт холст размером 800x600, на котором камера будет "плавать" по изображению 1920x1080.
Что попробовать дальше
Установка границ для камеры — фундаментальный приём для игр с миром, большим чем экран. Использование SmoothedKeyControl — удобный способ быстро добавить отладочное или катсценное управление камерой. Для экспериментов попробуйте:
1. Сменить изображение на тайлмап, созданный в Tiled, и установить границы в его размер.
2. Привязать камеру к спрайту игрока, используя this.cameras.main.startFollow(sprite). Камера будет автоматически следовать за ним, но останавливаться у установленных вами границ.
3. Поиграть с параметрами acceleration, drag и maxSpeed, чтобы добиться разного "ощущения" от движения камеры.
