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

Отражение спрайтов – один из базовых, но крайне полезных приёмов в геймдеве. Он позволяет создавать анимации ходьбы в обе стороны, зеркалить окружение и даже реализовывать головоломки с симметрией, используя всего один набор текстур. В этой статье мы разберём три способа отражения изображения по оси Y в Phaser 3: через метод `setFlipY`, свойство `flipY` и метод `toggleFlipY`. Это знание сэкономит вам ресурсы и упростит работу с графикой.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('pic', 'assets/pics/cougar-face-of-nature.png');
    }

    create ()
    {
        //  Default non-flipped image
        this.add.image(250, 164, 'pic');

        //  Flipped via a call to setFlipY
        this.add.image(250, 464, 'pic').setFlipY(true);

        const image = this.add.image(650, 164, 'pic');

        //  Flipped via setting the flipY property
        image.flipY = true;

        const image2 = this.add.image(650, 464, 'pic');

        this.input.on('pointerdown', () =>
        {

            //  Flipped via a call to toggleFlipX
            image2.toggleFlipY();

        });
    }
}

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Загрузка изображения и базовое отображение

Всё начинается с загрузки ресурса и его стандартного отображения на сцене. В методе preload мы устанавливаем базовый URL и загружаем одно изображение под ключом 'pic'.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.image('pic', 'assets/pics/cougar-face-of-nature.png');
}

В create мы сначала размещаем изображение в его оригинальной, неперевёрнутой форме. Это наша точка отсчёта.

//  Default non-flipped image
this.add.image(250, 164, 'pic');

Метод setFlipY: отражение при создании

Первый и самый прямой способ – использовать метод setFlipY. Этот метод вызывается цепочкой сразу после создания игрового объекта (Image) и принимает булево значение: true для отражения, false – чтобы вернуть исходный вид.

//  Flipped via a call to setFlipY
this.add.image(250, 464, 'pic').setFlipY(true);

Этот подход удобен, когда вы заранее знаете, что объект должен быть отражён, и не планируете менять это состояние позже в кадре. Метод setFlipY возвращает сам экземпляр изображения, что позволяет строить такие цепочки вызовов.

Свойство flipY: прямое управление состоянием

Второй способ – напрямую обратиться к свойству flipY объекта. Это обычное свойство, которое также принимает булево значение. Этот стиль может показаться более интуитивным, если вы привыкли работать со свойствами, а не с методами-сеттерами.

const image = this.add.image(650, 164, 'pic');

//  Flipped via setting the flipY property
image.flipY = true;

Обращение к свойству особенно полезно в условиях, когда нужно проверить текущее состояние отражения (if (image.flipY) { ... }), или когда значение вычисляется динамически.

Метод toggleFlipY: интерактивное переключение

Третий способ идеален для интерактивных сценариев, когда состояние отражения нужно менять в ответ на действия игрока. Метод toggleFlipY переключает текущее значение flipY на противоположное.

const image2 = this.add.image(650, 464, 'pic');

this.input.on('pointerdown', () =>
{
    //  Flipped via a call to toggleFlipX
    image2.toggleFlipY();
});

В примере при каждом клике мышью изображение image2 будет переворачиваться по вертикали и возвращаться обратно. Это отличный способ реализовать простую анимацию или реакцию объекта на клик без написания дополнительной логики для проверки текущего состояния.

Конфигурация игры и запуск

Весь функционал упаковывается в стандартную конфигурацию Phaser.Game. Ключевой момент – указание нашего класса сцены Example в конфиге.

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Именно этот объект game инициализирует движок, создаёт канвас и запускает жизненный цикл сцены (preload, create, update).

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

Как видите, Phaser 3 предлагает несколько элегантных способов отражения изображений: setFlipY для первоначальной настройки, свойство flipY для прямого контроля и toggleFlipY для интерактивного переключения. Эти методы работают не только с Image, но и со Sprite и другими игровыми объектами. Для экспериментов попробуйте совместить отражение по оси Y с flipX, чтобы создать все 4 возможных ориентации одного спрайта, или анимируйте переворот в цикле update, чтобы имитировать вращение карты в карточной игре.