О чем этот пример

Создание глубины в 2D-играх часто достигается с помощью параллакс-скроллинга — техники, когда слои фона движутся с разной скоростью. Phaser предоставляет для этого простой и мощный инструмент — `setScrollFactor`. Эта статья покажет, как легко реализовать эффект параллакса, фиксированные элементы интерфейса и контролировать камеру, чтобы ваши игры выглядели профессионально и динамично.

Версия 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, scrolls at half the speed of the camera
        this.add.image(400, 300, 'hotdog').setScrollFactor(0.50);

        //  A sprite, scrolls at quarter the speed of the camera
        this.add.image(400, 300, 'hotdog').setScrollFactor(0.25);

        //  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

        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);

        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);

Что такое Scroll Factor?

Каждый игровой объект в Phaser (спрайт, изображение, текст) может быть привязан к движению камеры. Коэффициент прокрутки (scrollFactor) определяет, насколько быстро объект будет двигаться относительно камеры.

* scrollFactor: 1 (значение по умолчанию): Объект движется синхронно с камерой, как обычный элемент уровня. * scrollFactor: 0: Объект полностью зафиксирован на экране и не двигается при перемещении камеры. Идеально для элементов HUD. * scrollFactor: 0.5: Объект движется в два раза медленнее камеры, создавая эффект дальнего фона (параллакс).

Метод setScrollFactor(x, y) задаёт коэффициент для обеих осей. Если передать одно число, оно будет применено к обеим осям.

Разбираем код примера

В примере создаётся сцена с четырьмя слоями, имеющими разную скорость прокрутки.

Сначала загружаются ресурсы: фоновое изображение вулкана и спрайт хот-дога.

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 добавляются объекты с разными коэффициентами прокрутки. Все они размещены в одной точке (400, 300), но из-за разного scrollFactor будут вести себя по-разному при движении камеры.

create ()
{
    //  Фон - прокручивается вместе с камерой 1:1
    this.add.image(400, 300, 'volcano'); // scrollFactor по умолчанию = 1

    //  Спрайт, прокручивается в 2 раза медленнее камеры
    this.add.image(400, 300, 'hotdog').setScrollFactor(0.50);

    //  Спрайт, прокручивается в 4 раза медленнее камеры
    this.add.image(400, 300, 'hotdog').setScrollFactor(0.25);

    //  Спрайт, зафиксированный на камере (не прокручивается)
    this.add.image(400, 300, 'hotdog').setScrollFactor(0);
}

Фон (volcano) имеет коэффициент по умолчанию (1) и движется как "земля". Три спрайта hotdog представляют собой слои с параллакс-эффектом (0.5, 0.25) и фиксированный элемент (0).

Управление камерой и отладка

Чтобы увидеть эффект в действии, пример добавляет плавное управление камерой с клавиатуры и панель отладки.

Создаётся объект управления SmoothedKeyControl, который связывает стрелки клавиатуры с перемещением основной камеры (this.cameras.main).

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);

Для наглядности используется библиотека dat.GUI. Она выводит текущие свойства камеры (координаты `x,y, смещениеscrollX,scrollYи вращениеrotation`) в реальном времени, позволяя наблюдать, как меняются эти значения при движении.

var cam = this.cameras.main;
const gui = new dat.GUI();
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.open();

В методе update обновляется состояние контролов камеры.

update (time, delta)
{
    this.controls.update(delta);
}

Практическое применение

1. **Параллакс для фонов:** Создайте несколько слоёв (горы, облака, деревья) с убывающим scrollFactor (например, 0.8, 0.6, 0.3). Это мгновенно добавит игре ощущение глубины и объёма. 2. **Фиксированный интерфейс:** Используйте setScrollFactor(0) для отображения здоровья, очков, кнопок паузы или мини-карты. Эти элементы всегда будут на одном месте экрана. 3. **Локальные анимации:** Объект с scrollFactor: 0 можно анимировать независимо от камеры (например, мигающий индикатор). 4. **Несимметричный параллакс:** Метод setScrollFactor(0.5, 0) заставит объект двигаться только по горизонтали, создавая интересный визуальный эффект при вертикальном скроллинге уровня.

Важно помнить, что scrollFactor применяется к мировым координатам объекта. Фиксированный объект, добавленный в мировую точку (400, 300), будет отображаться в центре экрана, куда бы вы ни переместили камеру.

Что попробовать дальше

Метод setScrollFactor — это ключ к созданию динамичных и визуально богатых 2D-сцен в Phaser. Он прост в использовании, но открывает огромные возможности: от классического параллакса до сложных интерфейсов. **Идеи для экспериментов:** * Создайте сцену с 5+ слоями параллакса. * Свяжите коэффициент прокрутки слоя со скоростью движения игрока для кинематографичного эффекта. * Реализуйте "режим карты" или бинокля, где один слой (scrollFactor: 0) является статичной маской, а фон под ним (scrollFactor: 1) можно исследовать, двигая камеру.