О чем этот пример
Создание динамического игрового фона — частая задача в разработке игр. Использование обычных картинок может привести к неэффективному расходованию памяти и сложностям с анимацией. В этой статье разберем, как с помощью объекта `TileSprite` в Phaser 3 легко создавать бесшовные, бесконечно повторяющиеся и плавно анимированные фоны. Этот подход идеально подходит для параллакс-эффектов, анимированных небес, воды или текстурных поверхностей.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
iter = 0;
tween;
image1;
image0;
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('image0', 'assets/pics/ra-einstein.png');
this.load.image('image1', 'assets/sprites/mushroom2.png');
}
create ()
{
this.image0 = this.add.tileSprite(400, 300, 800, 600, 'image0');
this.image1 = this.add.tileSprite(400, 300, 250, 250, 'image1');
this.tween = this.tweens.addCounter({
from: 1,
to: 2,
duration: 5000,
ease: 'Sine.easeInOut',
yoyo: true,
repeat: -1
});
}
update ()
{
this.image0.tilePositionX = Math.cos(this.iter) * 700;
this.image0.tilePositionY = Math.sin(this.iter) * 500;
this.image0.tileScaleX = this.tween.getValue();
this.image0.tileScaleY = this.tween.getValue();
this.image1.tilePositionX = Math.cos(-this.iter) * 400;
this.image1.tilePositionY = Math.sin(-this.iter) * 400;
this.iter += 0.01;
}
}
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Что такое TileSprite?
TileSprite — это особый тип игрового объекта в Phaser, который рисует текстуру с эффектом тайлинга (повторения). В отличие от обычного Sprite, он не ограничен одним экземпляром изображения. Его можно мысленно представить как прямоугольную область, заполненную плитками одного изображения.
Главное преимущество — возможность управлять положением (tilePosition) и масштабом (tileScale) самой текстуры внутри этого спрайта. Сдвигая текстуру, мы создаем иллюзию движения, при этом сам спрайт остается на месте в игре. Это очень производительно и экономит ресурсы.
В нашем примере создаются два TileSprite: один на весь экран с портретом, второй — поменьше, со спрайтом гриба.
Создание и настройка TileSprite
Создаются тайл-спрайты в методе create сцены. Ключевой метод — this.add.tileSprite(x, y, width, height, textureKey).
this.image0 = this.add.tileSprite(400, 300, 800, 600, 'image0');
this.image1 = this.add.tileSprite(400, 300, 250, 250, 'image1');
Здесь:
* x, y — координаты центра спрайта на холсте.
* width, height — размеры прямоугольной области, которую будет занимать спрайт. Для image0 это размеры всего игрового окна (800x600).
* textureKey — ключ текстуры, загруженной в preload.
Также в create создается твин — плавно меняющееся значение для анимации масштаба.
this.tween = this.tweens.addCounter({
from: 1,
to: 2,
duration: 5000,
ease: 'Sine.easeInOut',
yoyo: true,
repeat: -1
});
tweens.addCounter создает твин для числового значения, которое будет циклично колебаться между 1 и 2 с плавным ускорением и замедлением (Sine.easeInOut).
Анимация в методе Update
Вся магия движения происходит в методе update, который вызывается на каждом кадре. Мы анимируем два свойства каждого TileSprite.
**1. Положение текстуры (tilePosition):**
Сдвигаем начальную точку отрисовки текстуры, используя тригонометрические функции для плавного циклического движения.
this.image0.tilePositionX = Math.cos(this.iter) * 700;
this.image0.tilePositionY = Math.sin(this.iter) * 500;
Для image1 движение идет в противоположную фазу (-this.iter), создавая интересный визуальный контраст.
**2. Масштаб текстуры (tileScale):**
Меняем масштаб повторяемой текстуры, используя значение из созданного ранее твина.
this.image0.tileScaleX = this.tween.getValue();
this.image0.tileScaleY = this.tween.getValue();
Значение this.tween.getValue() плавно меняется от 1 до 2 и обратно, заставляя текстуру фона периодически "зумироваться".
Переменная this.iter увеличивается на каждом кадре, выступая в роли угла для расчета синуса и косинуса.
this.iter += 0.01;
Конфигурация игры и запуск
Код завершается стандартной для Phaser 3 конфигурацией игры. Обратите внимание, что в type указан Phaser.WEBGL для использования аппаратного рендеринга.
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
scene: Example
};
const game = new Phaser.Game(config);
Эта конфигурация создает игровой холст размером 800x600 пикселей с темно-серым фоном и инициирует создание экземпляра нашей сцены Example.
Что попробовать дальше
TileSprite — мощный и простой инструмент для создания сложной на вид анимации фона с минимальными затратами. Экспериментируйте: попробуйте разные функции для tilePosition (например, привяжите к скорости игрока для эффекта параллакса), используйте отдельные твины для масштаба по осям X и Y, или накладывайте несколько слоев TileSprite с разной скоростью движения для создания глубины. Это основа для динамичных фонов в платформерах, шутерах или аркадах.
