О чем этот пример

В этой статье мы разберём, как создать основу для классического платформера в Phaser 3, используя физический движок Arcade. Вы научитесь загружать графические ресурсы, настраивать физику мира и размещать неподвижные платформы, которые будут служить твёрдой поверхностью для игрового персонажа. Этот фундаментальный шаг необходим для любой игры, где герой должен прыгать по платформам, избегать препятствий или собирать предметы.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    platforms;

    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');
    }

    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() отвечает за предварительную загрузку всех необходимых изображений и спрайтов в кеш движка. Это критически важный этап, так как попытка использовать ресурс до его загрузки приведёт к ошибке. Обратите внимание на использование метода load.spritesheet для загрузки спрайт-листа персонажа, где необходимо указать размер каждого кадра.

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 });

Конфигурация игры и физического движка

Объект config определяет основные параметры игры. Ключевым разделом здесь является physics. Мы устанавливаем default: 'arcade', что активирует простой и быстрый физический движок Phaser.

Внутри настроек Arcade мы задаём гравитацию по оси Y (gravity: { y: 300 }). Это означает, что все физические тела (кроме статичных) будут притягиваться вниз с ускорением 300 пикселей в секунду за секунду. Параметр debug: false отключает отладочную визуалицию хитбоксов, которую полезно включить на этапе разработки.

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 300 },
            debug: false
        }
    },
    scene: Example
};

Создание мира: фон и статичная группа

Метод create() выполняется один раз после успешной загрузки всех ресурсов. Здесь происходит построение игрового мира.

Сначала мы добавляем фоновое изображение неба с помощью this.add.image(400, 300, 'sky'). Координаты (400, 300) — это центр холста размером 800x600.

Затем создаётся физическая статичная группа: this.platforms = this.physics.add.staticGroup(). Статичная группа (staticGroup) — это мощный инструмент Phaser для управления множеством тел, которые не подвержены гравитации и не могут двигаться под воздействием сил или столкновений. Они идеально подходят для земли, платформ и стен.

this.platforms = this.physics.add.staticGroup();

Размещение и настройка платформ

После создания группы мы наполняем её конкретными объектами. Каждый вызов this.platforms.create() добавляет в группу новый статичный спрайт с физическим телом.

Первая платформа создаётся внизу экрана: this.platforms.create(400, 568, 'ground'). Метод setScale(2) увеличивает её размер в два раза по осям X и Y, чтобы она стала шире. Важный нюанс: после изменения масштаба статичного физического тела необходимо вручную обновить его размер, вызвав .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');

Что попробовать дальше

Теперь у вас есть полноценная сцена с физическим миром, гравитацией и набором статичных платформ. Это готовый фундамент для добавления динамического персонажа, который сможет по ним прыгать. Для экспериментов попробуйте: изменить координаты и количество платформ, чтобы создать более сложный уровень; включить debug: true в конфиге, чтобы увидеть границы физических тел; поэкспериментировать с силой гравитации, задав другое значение `y`.