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

При создании анимации в Phaser есть параметр `showOnStart`, который часто остается незамеченным, но решает распространенную проблему. Часто разработчики создают спрайты с начальным состоянием `visible: false`, а затем вручную включают видимость перед запуском анимации. Опция `showOnStart` автоматизирует этот процесс, делая код чище и логичнее. В этой статье мы разберем пример, где группа невидимых птиц оживает по клику мыши. Ключевой момент — анимация не только запускает движение, но и волшебным образом проявляет спрайт на экране, благодаря одной настройке.

Версия 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.atlas('bird', 'assets/animations/bird.png', 'assets/animations/bird.json');
    }

    create ()
    {
        this.add.text(400, 32, 'Click to get the next sprite', { color: '#00ff00' }).setOrigin(0.5, 0);

        var animConfig = {
            key: 'walk',
            frames: this.anims.generateFrameNames('bird', { prefix: 'frame', end: 9 }),
            repeat: -1,
            showOnStart: true
        };

        this.anims.create(animConfig);

        //  Create a bunch of random sprites
        const rect = new Phaser.Geom.Rectangle(64, 64, 672, 472);

        const group = this.add.group();
        group.createMultiple({ key: 'bird', frame: 0, quantity: 64, visible: false, active: false });

        //  Randomly position the sprites within the rectangle
        Phaser.Actions.RandomRectangle(group.getChildren(), rect);

        this.input.on('pointerdown', function () {

            const bird = group.getFirstDead();

            if (bird)
            {
                bird.active = true;
                bird.setDepth(bird.y);

                //  As soon as we play the animation, the Sprite will be made visible
                bird.play('walk');
            }

        });
    }
}

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    pixelArt: true,
    scene: Example
};

const game = new Phaser.Game(config);

Подготовка анимации: ключевая конфигурация

Вся магия начинается в методе create. Здесь мы создаем конфигурационный объект для анимации, где и задается параметр showOnStart.

var animConfig = {
    key: 'walk',
    frames: this.anims.generateFrameNames('bird', { prefix: 'frame', end: 9 }),
    repeat: -1,
    showOnStart: true
};

Разберем параметры: - key: 'walk' — уникальное имя анимации для ее последующего вызова. - frames — кадры генерируются из атласа bird с именами от frame0 до frame9. - repeat: -1 — анимация зацикливается бесконечно. - **showOnStart: true** — вот тот самый важный флаг. Когда анимация walk будет проигрываться на спрайте, она автоматически установит его свойство visible в true, даже если изначально оно было false.

После создания конфигурации мы регистрируем анимацию в системе:

this.anims.create(animConfig);

Создание пула невидимых спрайтов

Прежде чем что-то оживить, нужно это создать. В примере формируется группа из 64 спрайтов, которые изначально неактивны и невидимы.

const group = this.add.group();
group.createMultiple({ key: 'bird', frame: 0, quantity: 64, visible: false, active: false });

Параметры createMultiple: - key: 'bird' — текстура для спрайтов. - frame: 0 — начальный статичный кадр. - quantity: 64 — количество создаваемых спрайтов. - visible: false — спрайты создаются невидимыми. - active: false — спрайты помечаются как "неактивные" (в терминологии Group это означает "мертвые").

Затем спрайты случайным образом распределяются по заданной прямоугольной области:

const rect = new Phaser.Geom.Rectangle(64, 64, 672, 472);
Phaser.Actions.RandomRectangle(group.getChildren(), rect);

Теперь у нас есть 64 птицы, готовые к оживлению, но пока скрытые от глаз.

Оживление по клику: где срабатывает showOnStart

Механика оживления привязана к событию клика мыши. По каждому клику мы берем первого "мертвого" (неактивного) спрайта из группы и запускаем на нем процесс.

this.input.on('pointerdown', function () {
    const bird = group.getFirstDead();
    if (bird) {
        bird.active = true;
        bird.setDepth(bird.y);
        bird.play('walk');
    }
});

Последовательность действий: 1. group.getFirstDead() — получаем ссылку на первый неактивный спрайт. 2. bird.active = true — помечаем его как активный ("живой"), чтобы при следующем клике он не был выбран снова. 3. bird.setDepth(bird.y) — устанавливаем глубину отрисовки на основе координаты Y, чтобы нижние спрайты перекрывались верхними (параллакс-эффект). 4. **bird.play('walk')** — ключевая команда. Мы просим спрайт проиграть анимацию walk.

И вот здесь вступает в силу параметр showOnStart: true, который мы задали при создании анимации. В момент вызова .play('walk') система анимации Phaser проверяет эту настройку и автоматически выполняет bird.visible = true. Нам не нужно делать это вручную! Спрайт становится видимым и сразу начинает анимироваться.

Почему это удобно и когда использовать

Использование showOnStart делает код более декларативным и сосредоточенным на логике, а не на управлении состоянием. Вы определяете поведение анимации («при старте покажи спрайт») один раз при ее создании, а не каждый раз при запуске.

Без showOnStart обработчик клика выглядел бы так:

if (bird) {
    bird.active = true;
    bird.setDepth(bird.y);
    bird.visible = true; // Пришлось бы добавлять эту строку
    bird.play('walk');
}

Параметр showOnStart идеально подходит для сценариев, где: - Спрайты создаются скрытыми (например, как часть пула объектов). - Их появление на экране должно совпадать с началом анимации. - Вы хотите уменьшить количество повторяющегося кода для включения видимости.

Это отличный пример того, как изучение параметров API Phaser помогает писать более лаконичный и выразительный код.

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

Опция showOnStart — небольшой, но мощный инструмент для управления видимостью спрайтов через их анимацию. Она позволяет связать логику появления объекта с логикой его движения, делая код чище. Идеи для экспериментов: 1. Попробуйте создать анимацию с showOnStart: false. Запустите ее на видимом спрайте, а затем на невидимом. Убедитесь, что невидимый спрайт так и останется скрытым. 2. Создайте две анимации для одного спрайта: одну с showOnStart: true, другую с false. Переключайтесь между ними и наблюдайте за изменением свойства visible. 3. Используйте этот прием в связке с другими событиями анимации, например onStart или onComplete, чтобы строить более сложные цепочки появления и исчезновения игровых объектов.