О чем этот пример
Создание игровых механик часто требует точного контроля над временем — например, для периодического спауна врагов, мигания объектов или анимации по таймеру. Встроенная система времени Phaser (`Phaser.Time`) предоставляет мощный инструмент `TimeEvent` для решения этих задач. В этой статье мы разберем, как работает повторяющееся событие, как отслеживать его прогресс и использовать для управления игровыми объектами.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
timedEvent;
text;
image;
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('einstein', 'assets/pics/ra-einstein.png');
}
create ()
{
this.image = this.add.image(400, 300, 'einstein');
this.text = this.add.text(32, 32);
this.timedEvent = this.time.addEvent({ delay: 2000, callback: this.onEvent, callbackScope: this, repeat: 4 });
}
update ()
{
this.text.setText(`Event.progress: ${this.timedEvent.getProgress().toString().substr(0, 4)}\nEvent.repeatCount: ${this.timedEvent.repeatCount}`);
}
onEvent ()
{
this.image.scaleX *= 0.90;
this.image.scaleY *= 0.90;
this.image.rotation += 0.04;
}
}
const config = {
type: Phaser.CANVAS,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Подготовка сцены и загрузка ассетов
Класс Example расширяет Phaser.Scene. В методе preload() задается базовый URL для загрузки и загружается одно изображение. Это стандартный подход для подготовки ресурсов перед созданием сцены.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('einstein', 'assets/pics/ra-einstein.png');
}
Создание события с повторениями
В методе create() мы создаем изображение и текстовый объект для отладки. Ключевой момент — создание TimeEvent через this.time.addEvent(). Конфигурационный объект принимает несколько параметров:
- delay: интервал между вызовами в миллисекундах (2000 мс = 2 секунды).
- callback: функция, которая будет вызываться по истечении каждого интервала.
- callbackScope: контекст (this), в котором будет вызываться функция обратного вызова.
- repeat: количество *дополнительных* повторений после первого срабатывания. Значение 4 означает, что событие произойдет 5 раз (1 начальное + 4 повторения).
create ()
{
this.image = this.add.image(400, 300, 'einstein');
this.text = this.add.text(32, 32);
this.timedEvent = this.time.addEvent({ delay: 2000, callback: this.onEvent, callbackScope: this, repeat: 4 });
}
Отслеживание прогресса события
Метод update() вызывается каждый кадр. Здесь мы обновляем текстовую метку, чтобы визуализировать состояние таймера. Мы используем два свойства объекта timedEvent:
- getProgress(): возвращает число от 0 до 1, представляющее общий прогресс всего события (всех повторений). Мы обрезаем строку для краткости отображения.
- repeatCount: текущее количество оставшихся повторений. Обратите внимание, что это обратный отсчет. После каждого срабатывания callback значение уменьшается на 1.
update ()
{
this.text.setText(`Event.progress: ${this.timedEvent.getProgress().toString().substr(0, 4)}\nEvent.repeatCount: ${this.timedEvent.repeatCount}`);
}
Логика обратного вызова
Функция onEvent() — это наша пользовательская логика, которая выполняется по таймеру. В данном примере при каждом вызове изображение немного уменьшается (scale умножается на 0.9) и поворачивается. Это демонстрирует, как можно использовать событие для постепенной трансформации объекта.
onEvent ()
{
this.image.scaleX *= 0.90;
this.image.scaleY *= 0.90;
this.image.rotation += 0.04;
}
Что попробовать дальше
TimeEvent — это фундаментальный инструмент для создания интервальных действий в Phaser. Экспериментируйте: попробуйте изменить параметры delay и repeat, остановите событие методом timedEvent.remove(), перезапустите его или создайте цепочку событий с разной логикой в callback. Это основа для таймеров обратного отсчета, систем волн противников и цикличной анимации.
