О чем этот пример
В динамичных играх часто нужно закрепить некоторые элементы интерфейса (например, здоровье, паузу или таймер) так, чтобы они всегда оставались на одном месте экрана, независимо от перемещения камеры. В Phaser для этого используется простой и мощный метод `setScrollFactor`. Эта статья покажет, как отделить фоновые объекты от элементов HUD, используя возможности камеры. Вы научитесь управлять поведением спрайтов при скроллинге и создадите основу для сложных игровых интерфейсов.
Версия 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('volcano', 'assets/pics/the-end-by-iloe-and-made.jpg');
this.load.image('hotdog', 'assets/sprites/hotdog.png');
}
create ()
{
// A background image - scrolls with the camera at a 1:1 ratio
this.add.image(400, 300, 'volcano');
// A sprite, doesn't scroll with the camera (is fixed to camera)
this.add.image(400, 300, 'hotdog').setScrollFactor(0);
// From here down is just camera controls and feedback
var cursors = this.input.keyboard.createCursorKeys();
var 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);
var cam = this.cameras.main;
const gui = new dat.GUI();
var help = {
line1: 'Cursors to move'
}
var f1 = gui.addFolder('Camera');
f1.add(cam, 'x').listen();
f1.add(cam, 'y').listen();
f1.add(cam, 'scrollX').listen();
f1.add(cam, 'scrollY').listen();
f1.add(cam, 'rotation').min(0).step(0.01).listen();
f1.add(help, 'line1');
f1.open();
}
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);
Загрузка ресурсов: фон и спрайт
В примере загружаются два изображения: фоновое изображение вулкана и спрайт хот-дога. Обратите внимание, что в методе preload используется setBaseURL, чтобы задать базовый путь для загрузки, что удобно для работы с внешними ресурсами.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('volcano', 'assets/pics/the-end-by-iloe-and-made.jpg');
this.load.image('hotdog', 'assets/sprites/hotdog.png');
}
Создание объектов и настройка скроллинга
В методе create сначала добавляется фоновое изображение. По умолчанию в Phaser объекты движутся вместе с камерой, то есть имеют scrollFactor, равный 1.
// A background image - scrolls with the camera at a 1:1 ratio
this.add.image(400, 300, 'volcano');
Затем добавляется спрайт хот-дога, но для него сразу вызывается метод setScrollFactor(0). Это ключевой момент: установка фактора прокрутки в 0 фиксирует объект относительно камеры. Теперь при движении камеры хот-дог будет оставаться на одном месте экрана.
// A sprite, doesn't scroll with the camera (is fixed to camera)
this.add.image(400, 300, 'hotdog').setScrollFactor(0);
Управление камерой с плавным контролем
Чтобы продемонстрировать эффект фиксации, в примере реализовано управление камерой с клавиатуры. Для этого используется встроенный класс Phaser.Cameras.Controls.SmoothedKeyControl, который обеспечивает плавное ускорение и замедление движения.
Конфигурация контрола передаёт ссылку на основную камеру this.cameras.main и привязывает управление к стрелкам клавиатуры. Параметры acceleration, drag и maxSpeed настраивают физику движения.
var cursors = this.input.keyboard.createCursorKeys();
var 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 состояние контрола обновляется каждый кадр, обеспечивая движение камеры.
update (time, delta)
{
this.controls.update(delta);
}
Визуализация параметров камеры
Для наглядности в примере используется библиотека dat.GUI, чтобы в реальном времени отображать параметры камеры. Это помогает понять, как изменяются её свойства при движении.
В интерфейс выводятся текущие координаты камеры (`x,y), значения смещения (scrollX,scrollY) и вращение (rotation). Обратите внимание, что для свойств, которые должны обновляться в реальном времени, вызывается метод.listen()`.
var cam = this.cameras.main;
const gui = new dat.GUI();
var help = {
line1: 'Cursors to move'
}
var f1 = gui.addFolder('Camera');
f1.add(cam, 'x').listen();
f1.add(cam, 'y').listen();
f1.add(cam, 'scrollX').listen();
f1.add(cam, 'scrollY').listen();
f1.add(cam, 'rotation').min(0).step(0.01).listen();
f1.add(help, 'line1');
f1.open();
Что попробовать дальше
Метод setScrollFactor — это простой и эффективный способ разделить мир игры и её интерфейс. Фиксируя спрайты относительно камеры, вы создаёте стабильную область для отображения важной информации. Для экспериментов попробуйте задать спрайту setScrollFactor(0.5), чтобы он двигался с половинной скоростью относительно камеры, создавая эффект параллакса. Также можно применить этот подход к целым группам объектов или текстовым элементам для построения сложного HUD.
