О чем этот пример
Любой платформер начинается с двух ключевых элементов: физики и анимации. В этой статье мы разберем, как создать базовую физическую модель персонажа, добавить ему реалистичное движение и настроить анимации для бега и покоя, используя пример из официальной документации Phaser. Вы научитесь работать с группами статических тел, коллизиями и спрайтшитами — фундаментом для будущих игр.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
platforms;
player;
preload ()
{
// this.load.setBaseURL('https://cdn.phaserfiles.com/v385');
this.load.image('sky', 'src/games/firstgame/assets/sky.png');
this.load.image('ground', 'src/games/firstgame/assets/platform.png');
this.load.image('star', 'src/games/firstgame/assets/star.png');
this.load.image('bomb', 'src/games/firstgame/assets/bomb.png');
this.load.spritesheet('dude', 'src/games/firstgame/assets/dude.png', { frameWidth: 32, frameHeight: 48 });
}
create ()
{
this.add.image(400, 300, 'sky');
this.platforms = this.physics.add.staticGroup();
this.platforms.create(400, 568, 'ground').setScale(2).refreshBody();
this.platforms.create(600, 400, 'ground');
this.platforms.create(50, 250, 'ground');
this.platforms.create(750, 220, 'ground');
this.player = this.physics.add.sprite(100, 450, 'dude');
this.player.setBounce(0.2);
this.player.setCollideWorldBounds(true);
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'turn',
frames: [ { key: 'dude', frame: 4 } ],
frameRate: 20
});
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('dude', { start: 5, end: 8 }),
frameRate: 10,
repeat: -1
});
this.physics.add.collider(this.player, this.platforms);
}
update ()
{
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: Example
};
const game = new Phaser.Game(config);
Подготовка ресурсов: загружаем текстурный атлас и изображения
В методе preload происходит загрузка всех необходимых ресурсов для сцены. Важно обратить внимание на два разных типа загрузки: для одиночных изображений и для спрайтшитов.
this.load.image загружает обычные статичные изображения, такие как фон, платформы, звезды и бомбы.
Спрайтшит — это одно изображение, содержащее несколько кадров анимации. Метод this.load.spritesheet загружает его и сразу указывает размер одного кадра (frameWidth и frameHeight), что позволяет Phaser автоматически нарезать его на отдельные фреймы.
this.load.image('sky', 'src/games/firstgame/assets/sky.png');
this.load.spritesheet('dude', 'src/games/firstgame/assets/dude.png', { frameWidth: 32, frameHeight: 48 });
Создание мира: фон и статические платформы
Метод create — это место, где мы конструируем игровой мир. Сначала добавляется фоновое изображение с помощью this.add.image. Важно: этот объект не имеет физического тела и не участвует в столкновениях.
Затем создается группа статических физических тел this.physics.add.staticGroup(). Статические тела неподвижны и не подвержены силам (вроде гравитации), но с ними могут сталкиваться динамические объекты. Это идеально подходит для платформ и земли.
Метод create у группы добавляет новое статическое тело. Метод refreshBody() необходимо вызывать, если вы изменяете размер (setScale) или положение статического тела после его создания, чтобы физический движок корректно пересчитал его границы.
this.platforms = this.physics.add.staticGroup();
this.platforms.create(400, 568, 'ground').setScale(2).refreshBody();
Персонаж: физическое тело и движение
Динамический персонаж создается как физический спрайт с помощью this.physics.add.sprite. В отличие от статических платформ, на него воздействует гравитация, заданная в конфигурации игры (y: 300).
Метод setBounce(0.2) задает упругость (коэффициент отскока) при столкновении с другими телами. Значение 0.2 означает, что 20% скорости будет сохранено после удара.
setCollideWorldBounds(true) — критически важный вызов. Он включает столкновения персонажа с границами игрового мира (800x600), не позволяя ему бесконечно падать вниз или уходить за края экрана.
this.player = this.physics.add.sprite(100, 450, 'dude');
this.player.setBounce(0.2);
this.player.setCollideWorldBounds(true);
Анимация: оживляем спрайт
Phaser использует систему анимаций, управляемую через this.anims.create. Каждая анимация имеет уникальный ключ (key), который используется для её воспроизведения.
Для бега влево и вправо мы используем this.anims.generateFrameNumbers, чтобы автоматически получить массив кадров из спрайтшита по их индексам (например, с 0 по 3). Параметр repeat: -1 заставляет анимацию зацикливаться.
Анимация 'turn' (поворот) состоит всего из одного кадра (кадр №4, где персонаж смотрит в камеру). Её можно использовать, когда игрок стоит на месте.
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1
});
Столкновения: связываем персонажа и платформы
Чтобы физика заработала, необходимо явно указать движку, какие объекты должны сталкиваться друг с другом. За это отвечает коллайдер.
this.physics.add.collider(this.player, this.platforms) регистрирует столкновение между динамическим спрайтом игрока и группой статических платформ. Благодаря этому персонаж будет останавливаться на платформах, а не проваливаться сквозь них под действием гравитации.
Этот метод — основа взаимодействия в платформере. Позже с его помощью можно будет добавить столкновения со звездами, врагами или другими объектами.
this.physics.add.collider(this.player, this.platforms);
Конфигурация игры: включаем физический движок
Вся физика в примере работает благодаря правильной конфигурации игры (const config). Ключевой раздел — physics.default: 'arcade'.
Включив аркадную физику (arcade), мы получаем простую и производительную систему для 2D-игр. В её настройках задается вектор гравитации (gravity: { y: 300 }), который заставляет все динамические тела падать вниз.
Параметр debug: false отключает отладочную отрисовку контуров физических тел. На этапе разработки его можно включить, чтобы визуально проверить расстановку коллайдеров.
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
}
Что попробовать дальше
Вы создали полноценную физическую сцену с персонажем, платформами и анимациями — основу для классического платформера. Теперь у вас есть прототип, который можно развивать. Для экспериментов попробуйте: изменить силу гравитации в конфиге, добавить персонажу горизонтальное ускорение в методе update, создать анимацию прыжка или добавить новые типы подвижных платформ в группу.
