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

Когда вы создаете игру, иногда нужно показать только часть игрового мира или выделить определенную область экрана. В Phaser за отображение отвечает система камер, и метод `setViewport` позволяет гибко управлять тем, какая область сцены будет видна на экране. Эта статья объяснит, как работает `setViewport`, и покажет практический пример его использования для создания динамичного "окна" в игровом мире.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
        this.iter = 0;
    }

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('einstein', 'assets/pics/ra-einstein.png');
    }

    create ()
    {
        this.image = this.add.image(0, 0, 'einstein');
        this.cameras.main.setViewport(200, 150, 400, 300);
    }

    update ()
    {
        this.image.x = Math.sin(this.iter) * 200;
        this.image.y = Math.cos(this.iter) * 200;
        this.iter += 0.04;
    }
}

const config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: Example,
};
const game = new Phaser.Game(config);

Что такое viewport (область просмотра) камеры

По умолчанию камера в Phaser отображает всю сцену в рамках холста игры. Однако вы можете изменить это поведение, задав viewport — прямоугольную область внутри холста, где будет отображаться содержимое камеры. Это полезно для создания эффектов разделенного экрана, UI-элементов, которые не должны перекрываться игрой, или для "приближения" к определенной части уровня.

Метод setViewport принимает четыре аргумента: координаты X и Y левого верхнего угла области на холсте, а также её ширину и высоту. Важно понимать, что эти координаты относятся к холсту (экрану), а не к координатам игрового мира.

Разбор примера: создание движущегося окна

Рассмотрим исходный код примера. В нем создается сцена, загружается изображение и устанавливается viewport для главной камеры.

Класс сцены инициализирует свойство iter для анимации:

constructor ()
{
    super();
    this.iter = 0;
}

В методе create происходит ключевое действие: установка viewport.

create ()
{
    this.image = this.add.image(0, 0, 'einstein');
    this.cameras.main.setViewport(200, 150, 400, 300);
}

Здесь setViewport(200, 150, 400, 300) означает, что содержимое камеры будет отображаться в прямоугольнике, начинающемся на 200 пикселей слева и 150 пикселей сверху от края холста. Размер этого прямоугольника — 400x300 пикселей. Вся остальная область холста (например, по краям) будет пустой или может быть заполнена другими элементами интерфейса.

Анимация и взаимодействие с viewport

В методе update изображение перемещается по кругу, используя тригонометрические функции.

update ()
{
    this.image.x = Math.sin(this.iter) * 200;
    this.image.y = Math.cos(this.iter) * 200;
    this.iter += 0.04;
}

Изображение einstein движется вокруг точки (0,0) мира. Однако из-за установленного viewport мы видим только ту часть мира, которая попадает в наше "окно" размером 400x300 пикселей, расположенное в центре холста 800x600. Движение изображения происходит в мировых координатах, а viewport лишь определяет, какая часть этих координат будет отображена в заданной области экрана. Это создает эффект, будто изображение "заглядывает" в статичное окно.

Конфигурация игры и итоговый результат

Конфигурация игры задает размер холста 800x600 пикселей.

const config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    scene: Example,
};
const game = new Phaser.Game(config);

При запуске вы увидите, что движущееся изображение Эйнштейна отображается не на всем холсте, а только в его центральной части (область 400x300). Края холста останутся пустыми. Это наглядная демонстрация изоляции viewport камеры от общего пространства отрисовки.

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

Метод cameras.main.setViewport — мощный инструмент для контроля над отображением игрового мира. Вы можете экспериментировать: создавать несколько камер с разными viewport для split-screen, анимировать параметры viewport для эффектов "дрожания" или "зума", или использовать отдельную камеру с маленьким viewport для мини-карты в углу экрана.