О чем этот пример
При создании анимации в 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, чтобы строить более сложные цепочки появления и исчезновения игровых объектов.
