О чем этот пример
Создание плавной, непрерывной анимации — основа визуального комфорта в играх. Ключевая проблема — заставить объекты двигаться с одинаковой скоростью на любых устройствах, независимо от частоты кадров. В этом примере из официальной коллекции Phaser показан элегантный паттерн для бесконечного скроллинга фонового элемента с использованием дельты времени (`delta`). Мы разберем, как это работает и почему это важно для производительности.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class SceneD extends Phaser.Scene {
constructor ()
{
super('SceneD');
this.planet;
}
create ()
{
this.cameras.main.setViewport(0, 136, 1024, 465);
this.planet = this.add.image(200, 380, 'space', 'planet');
}
update (time, delta)
{
this.planet.x += 0.01 * delta;
if (this.planet.x >= 1224)
{
this.planet.x = -200;
}
}
}
Инициализация сцены и объявление переменной
Класс сцены наследуется от Phaser.Scene. В конструкторе мы задаём системный ключ сцены и заранее объявляем переменную для нашего игрового объекта. Это хорошая практика для организации кода и дальнейшего доступа к объекту из других методов класса.
class SceneD extends Phaser.Scene {
constructor ()
{
super('SceneD');
this.planet;
}
Создание объектов и настройка камеры
Метод create() выполняется один раз при запуске сцены. Здесь мы задаём область просмотра (viewport) для основной камеры, позиционируя её в нужной части экрана. Затем создаём спрайт планеты, используя текстуру 'space' и конкретный кадр 'planet' из атласа. Позиция (200, 380) задаёт начальные координаты центра изображения.
create ()
{
this.cameras.main.setViewport(0, 136, 1024, 465);
this.planet = this.add.image(200, 380, 'space', 'planet');
}
Сердце анимации: метод update и delta
Метод update() вызывается на каждом кадре игры. Параметр delta — это ключевая величина. Он представляет время, прошедшее с предыдущего кадра, в миллисекундах. Умножая скорость на delta, мы привязываем движение не к количеству кадров, а к реальному времени. Это гарантирует, что планета будет перемещаться на 10 пикселей в секунду (0.01 * 1000ms = 10px/s) всегда, вне зависимости от FPS.
update (time, delta)
{
this.planet.x += 0.01 * delta;
}
Реализация бесконечного цикла (wrap-around)
Чтобы создать эффект бесконечного движения, мы отслеживаем позицию объекта. Когда координата `x` планеты превышает правую границу экрана (с учётом её ширины и начальной позиции), мы мгновенно перемещаем её за левую границу. Это создаёт иллюзию непрерывного космического фона.
if (this.planet.x >= 1224)
{
this.planet.x = -200;
}
}
Что попробовать дальше
Использование delta в update() — это фундаментальный паттерн для платформонезависимой анимации в Phaser. Для экспериментов попробуйте изменить константу 0.01, чтобы варьировать скорость. Добавьте вторую планету с другой скоростью для эффекта параллакса. Или замените простой перенос на плавное изменение через tweens для более сложных траекторий.
