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

Создание игр часто требует точного управления временем: появления врагов, запуск анимаций или смена фоновой музыки. Встроенный в Phaser класс `Timeline` позволяет легко и наглядно планировать любые события на временной линии, делая код чистым и управляемым. В этой статье мы разберем, как использовать Timeline для отложенного создания игровых объектов по клику мыши.

Версия 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.atlas('timeline', 'assets/atlas/timeline.png', 'assets/atlas/timeline.json');
        this.load.image('bg', 'assets/skies/spookysky.jpg');
    }

    create ()
    {
        this.add.image(400, 300, 'bg');

        this.add.text(10, 10, 'Click to add a sprite after 1 second', { font: '16px Courier', fill: '#ffffff' }).setDepth(1000);

        const timeline = this.add.timeline();

        timeline.play();

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

            timeline.add({
                in: 1000,
                once: true,
                run: () => {
                    const x = Phaser.Math.Between(100, 700);
                    const y = Phaser.Math.Between(100, 500);
                    this.add.sprite(x, y, 'timeline', 'pumpkin')
                }
            })

        });
    }
}

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

const game = new Phaser.Game(config);

Что такое Timeline и зачем он нужен

Timeline — это мощный инструмент в модуле времени (time) Phaser, представляющий собой линейную последовательность событий. В отличие от простых таймеров, таймлайн позволяет централизованно управлять множеством событий, задавать их задержку (in) и повторяемость (once).

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

Создание и запуск таймлайна

Первым делом необходимо создать экземпляр таймлайна и запустить его. Делается это в методе create() сцены.

const timeline = this.add.timeline();
timeline.play();

Метод this.add.timeline() создает новый объект Timeline. Вызов play() запускает его внутренний отсчет времени. Теперь таймлайн активен и готов принимать события.

Добавление событий в таймлайн по клику

Ключевая логика примера — добавление нового события в таймлайн при каждом клике мыши. Мы настраиваем слушатель события pointerdown.

this.input.on('pointerdown', () => {
    timeline.add({
        in: 1000,
        once: true,
        run: () => {
            const x = Phaser.Math.Between(100, 700);
            const y = Phaser.Math.Between(100, 500);
            this.add.sprite(x, y, 'timeline', 'pumpkin')
        }
    })
});

В объекте конфигурации, передаваемом в метод add, задаются параметры: - in: 1000 — задержка в миллисекундах (1 секунда), через которую произойдет событие. - once: true — флаг, указывающий, что событие сработает только один раз. - run — функция-коллбэк, которая будет выполнена после задержки. В ней генерируются случайные координаты и создается спрайт тыквы из атласа.

Как работает событие внутри Timeline

Когда вы кликаете, в таймлайн добавляется новое событие с относительной задержкой в 1 секунду от момента добавления. Timeline сам отслеживает время и вызывает функцию run, когда подходит его очередь.

run: () => {
    const x = Phaser.Math.Between(100, 700);
    const y = Phaser.Math.Between(100, 500);
    this.add.sprite(x, y, 'timeline', 'pumpkin')
}

Phaser.Math.Between генерирует случайное целое число в заданном диапазоне для координат X и Y. Метод this.add.sprite() создает на сцене спрайт, используя загруженный атлас 'timeline' и конкретный кадр (фрейм) из него с именем 'pumpkin'. Благодаря once: true это событие автоматически удаляется из таймлайна после выполнения.

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

Timeline в Phaser — это элегантное решение для планирования отложенных и повторяющихся действий. Он избавляет от необходимости создавать множество отдельных таймеров и улучшает структуру кода. Для экспериментов попробуйте: создать целую последовательность событий (add несколько раз с разным in) для кат-сцены; использовать once: false для периодического появления врагов; привязать к событиям не только создание спрайтов, но и воспроизведение звуков или запуск анимаций.