О чем этот пример
Эта статья проведёт вас по созданию базового платформера, используя пример из официальной документации Phaser. Мы разберём ключевые концепции, такие как загрузка ассетов, создание физических тел, настройка статичных платформ и анимации спрайта игрока. Понимание этого фундаментального примера даст вам прочную основу для разработки собственных 2D-игр с физикой в движке 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
});
}
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);
Настройка проекта и загрузка ресурсов
Класс сцены Example расширяет Phaser.Scene и содержит основные методы жизненного цикла. В методе preload() мы подгружаем все необходимые для уровня изображения и спрайтшит.
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 });
Здесь load.image() загружает обычные текстуры, а load.spritesheet() — лист анимации, где параметры frameWidth и frameHeight задают размер одного кадра. Это необходимо для последующего создания анимаций.
Создание мира и физических платформ
Метод create() инициализирует игровой мир. Сначала добавляется фоновое изображение sky.
this.add.image(400, 300, 'sky');
Затем создаётся статическая физическая группа platforms. Объекты в такой группе неподвижны и не реагируют на силы вроде гравитации, но с ними может сталкиваться динамические тела.
this.platforms = this.physics.add.staticGroup();
В эту группу добавляются несколько платформ из текстуры ground. Первая платформа масштабируется и требует вызова refreshBody(), чтобы физическое тело соответствовало новому визуальному размеру.
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.physics.add.sprite().
this.player = this.physics.add.sprite(100, 450, 'dude');
Ему задаются базовые физические свойства:
this.player.setBounce(0.2);
this.player.setCollideWorldBounds(true);
setBounce(0.2) определяет упругость (коэффициент отскока) при столкновениях. setCollideWorldBounds(true) включает столкновение спрайта с границами игрового мира, что не даст ему улететь за пределы холста.
Создание анимаций для спрайта
Phaser позволяет создавать анимации из кадров спрайтшита. В примере определены три анимации: движение влево, поворот (стойка) и движение вправо.
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1
});
key — это уникальное имя анимации для её последующего воспроизведения. frames задаёт последовательность кадров. this.anims.generateFrameNumbers() — удобный метод для генерации массива кадров из спрайтшита по их индексам (start, end). frameRate — скорость проигрывания в кадрах в секунду. repeat: -1 означает бесконечное повторение анимации, что идеально для циклической анимации бега.
Анимация turn использует один конкретный кадр (кадр №4) из спрайтшита.
Конфигурация игры и физический движок
Конфигурационный объект config передаётся в конструктор Phaser.Game. Здесь задаются базовые настройки приложения.
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: Example
};
Ключевой раздел — physics. Мы используем Arcade Physics, лёгкий 2D-физический движок Phaser. Параметр gravity: { y: 300 } устанавливает силу гравитации, которая будет действовать на все динамические тела по оси Y (вниз). debug: false отключает отладочную визуализацию коллайдеров. Класс Example указан как стартовая сцена игры.
Что попробовать дальше
Вы разобрали фундаментальный пример, который включает загрузку ассетов, создание статичного и динамического физического мира, а также анимацию спрайтов. Это основа для классического платформера. Для экспериментов попробуйте: изменить силу гравитации в конфиге, добавить больше платформ сложной формы, создать простую анимацию падения или прыжка для персонажа, либо включить debug-режим физики, чтобы увидеть контуры тел.
