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

Анимация движения, поворота или изменения прозрачности объектов — неотъемлемая часть игровой динамики. Часто требуется не просто запустить эффект сразу, а дать игроку контроль над ним: анимировать выстрел по нажатию кнопки, запустить анимацию падения блока после столкновения или активировать плавное появление меню. Механизм твинов (tweens) в Phaser 3 предоставляет для этого мощный инструментарий. В этой статье мы разберем, как создать твин в приостановленном (`paused`) состоянии и запустить его позже, по событию (например, клику мыши). Этот подход дает полный контроль над временем анимации, позволяет синхронизировать её с игровой логикой и создавать интерактивные, отзывчивые сцены.

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

Живой запуск

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

Исходный код


var text;
var tween;

class Example extends Phaser.Scene
{
    constructor()
    {
        super();
    }

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

    create()
    {
        var marker = this.add.image(100, 100, 'block').setAlpha(0.3);
        var image = this.add.image(100, 100, 'block');

        //  Creates a chained tween.

        var tween = this.tweens.add({
            targets: image,
            x: '+=600',
            ease: 'Power2',
            paused: true
        });

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

            tween.play();

        });

    }
}

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

const game = new Phaser.Game(config);

Создание сцены и загрузка ресурсов

Как и в любом проекте на Phaser, работа начинается с создания класса сцены, унаследованного от Phaser.Scene. В методе preload() мы загружаем необходимые ассеты. В данном примере это один спрайт — цветной блок.

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

Здесь setBaseURL задает базовый путь для загрузки, а this.load.image('block', ...) загружает изображение и присваивает ему текстовый ключ 'block'. Этот ключ будет использоваться для создания объектов из этого изображения в сцене.

Подготовка объектов и создание приостановленного твина

В методе create() происходит основная настройка сцены. Сначала создаются два графических объекта из одного и того же изображения 'block'. Первый, marker, служит статичным указателем начальной позиции, его прозрачность уменьшена с помощью setAlpha(0.3). Второй, image, — это тот объект, который мы будем анимировать.

create()
{
    var marker = this.add.image(100, 100, 'block').setAlpha(0.3);
    var image = this.add.image(100, 100, 'block');

Затем создается сам твин. Ключевой момент — параметр конфигурации paused: true. Он указывает системе твинов создать анимацию, но не запускать её автоматически. Твин будет ждать явной команды на старт.

var tween = this.tweens.add({
        targets: image, // Цель анимации — наш объект `image`
        x: '+=600',    // Свойство для изменения: координата X. Значение '+=600' означает смещение на 600 пикселей вправо от текущей позиции.
        ease: 'Power2', // Функция плавности (easing), определяющая характер движения. 'Power2' обеспечивает плавное ускорение и замедление.
        paused: true    // Самый важный параметр. Твин создается в приостановленном состоянии.
    });

Объект конфигурации передается в менеджер твинов сцены через this.tweens.add(). Метод возвращает экземпляр Tween, который мы сохраняем в переменную tween для дальнейшего управления.

Запуск твина по событию

Теперь нужно назначить событие, по которому твин будет запущен. В примере используется обработчик события клика (или касания) мыши pointerdown.

this.input.once('pointerdown', function ()
    {
        tween.play();
    });

Метод this.input.once() регистрирует обработчик, который сработает только один раз при первом клике на холсте. Внутри функции-обработчика вызывается метод .play() у сохраненного ранее экземпляра твина. Именно эта команда выводит твин из приостановленного состояния и начинает анимацию. Объект image плавно поедет вправо на 600 пикселей.

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

Финальный шаг — создание конфигурационного объекта для игры и инстанцирование Phaser.Game. В конфиге указывается сцена, размеры холста, цвет фона и родительский HTML-элемент.

const config = {
    type: Phaser.AUTO, // Автовыбор рендерера (WebGL или Canvas)
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d', // Темно-серый фон
    parent: 'phaser-example', // ID HTML-элемента для вставки игры
    scene: Example // Класс главной сцены
};

const game = new Phaser.Game(config);

После выполнения этого кода игра инициализируется, загрузится изображение, создастся сцена с двумя блоками. Анимация начнется только после первого клика пользователя по игровому полю.

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

Использование приостановленных твинов — это простой и эффективный способ связать анимацию с действиями игрока или внутренними событиями игры. Вы получили контроль над временем, отделив создание анимации от её выполнения. **Идеи для экспериментов:** 1. Попробуйте связать запуск твина не с кликом, а с другим событием, например, столкновением объектов (this.physics.add.collider). 2. Создайте цепочку твинов (chained tweens), где второй твин запускается после завершения первого, и управляйте началом всей цепочки. 3. Добавьте кнопку pause и resume для уже запущенного твина, используя методы .pause() и .resume() экземпляра Tween. 4. Поэкспериментируйте с разными свойствами (scale, alpha, angle) и функциями плавности (ease) в конфигурации твина.