О чем этот пример
В игровом движке Phaser обновление позиции спрайтов — одна из самых частых задач. В этой статье мы разберем, как правильно использовать метод `update()` для создания плавной анимации движения. Вы научитесь управлять координатами изображений и спрайтов из атласа, реализуете простой механизм «телепортации» при достижении границы экрана и поймете базовый принцип игрового цикла на практике.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
var config = {
type: Phaser.CANVAS,
parent: 'phaser-example',
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config);
var atlasFrame;
var singleImage;
function preload() {
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('atari', 'assets/sprites/atari130xe.png');
this.load.atlas('atlas', 'assets/atlas/megaset-0.png', 'assets/atlas/megaset-0.json');
}
function create() {
atlasFrame = this.add.image(0, 0, 'atlas', 'dragonwiz');
singleImage = this.add.image(200, 0, 'atari');
}
function update() {
singleImage.x += 4;
if (singleImage.x > this.game.config.width)
{
singleImage.x = 0;
singleImage.y += 64;
}
atlasFrame.x += 4;
if (atlasFrame.x > this.game.config.width)
{
atlasFrame.x = 0;
atlasFrame.y += 64;
}
}
Загрузка ресурсов в preload()
Перед созданием любых игровых объектов необходимо загрузить их графические ресурсы. В примере загружаются два типа ресурсов: отдельное изображение и атлас спрайтов.
function preload() {
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('atari', 'assets/sprites/atari130xe.png');
this.load.atlas('atlas', 'assets/atlas/megaset-0.png', 'assets/atlas/megaset-0.json');
}
Метод this.load.image() загружает одно изображение и присваивает ему ключ 'atari'. Метод this.load.atlas() загружает атлас — изображение, содержащее множество спрайтов, и JSON-файл с координатами кадров внутри него. Ключ 'atlas' будет использоваться для доступа ко всему атласу, а конкретный кадр выбирается по имени, например 'dragonwiz'.
Создание объектов в create()
После загрузки ресурсов в методе create() создаются игровые объекты — экземпляры класса Image. Они помещаются на сцену с заданными начальными координатами.
function create() {
atlasFrame = this.add.image(0, 0, 'atlas', 'dragonwiz');
singleImage = this.add.image(200, 0, 'atari');
}
Первый объект atlasFrame создается из атласа. Параметры метода this.add.image(): X=0, Y=0, ключ атласа 'atlas', имя кадра 'dragonwiz'. Второй объект singleImage создается из отдельного изображения с ключом 'atari' и смещен по оси X на 200 пикселей. Оба объекта размещаются в верхней части экрана, так как их координата Y равна 0.
Обновление позиций в update()
Метод update() вызывается на каждом кадре игры. Здесь происходит изменение состояния игровых объектов — в данном случае, их позиции.
function update() {
singleImage.x += 4;
if (singleImage.x > this.game.config.width) {
singleImage.x = 0;
singleImage.y += 64;
}
atlasFrame.x += 4;
if (atlasFrame.x > this.game.config.width) {
atlasFrame.x = 0;
atlasFrame.y += 64;
}
}
Каждый кадр координата X обоих объектов увеличивается на 4 пикселя, создавая иллюзию движения вправо. Условие if (singleImage.x > this.game.config.width) проверяет, вышел ли объект за правую границу экрана. Ширина экрана берется из конфигурации игры this.game.config.width. Если объект вышел за границу, его X сбрасывается в 0 (левая граница), а Y увеличивается на 64 пикселя, опуская объект на строку ниже. Это создает эффект «переноса» объекта на новую строку, подобно тексту на печатной машинке.
Ключевые моменты работы с координатами
Прямое изменение свойств .x и .y — самый простой способ перемещения объектов типа Image или Sprite. Важно помнить:
* Движение, описанное в update(), будет непрерывным и не зависит от частоты кадров (FPS) напрямую, так как метод вызывается каждый кадр. Однако для создания FPS-независимого движения требуются более сложные расчеты с учетом дельты времени.
* Свойство this.game.config.width содержит ширину игрового холста, заданную в конфигурации (или рассчитанную по умолчанию). Аналогично доступно this.game.config.height.
* Операция += модифицирует текущее значение переменной. Это стандартный и лаконичный способ инкремента.
Что попробовать дальше
Вы освоили базовый паттерн движения объектов в Phaser: загрузка, создание и обновление позиций в игровом цикле. Для экспериментов попробуйте: изменить скорость движения, задав другое значение вместо 4; реализовать движение по вертикали или диагонали; использовать this.game.config.height для «отскока» от нижней границы; добавить управление с клавиатуры, изменяя `xиy` по нажатию клавиш.
