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

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

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    sprite;

    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.image('sky', 'assets/skies/lightblue.png');
        this.load.image('elephant', 'assets/sprites/elephant.png');
    }

    create ()
    {
        this.add.image(0, 0, 'sky').setOrigin(0);

        this.sprite = this.add.sprite(400, 300, 'elephant');
    }

    update ()
    {
        if (this.input.gamepad.total === 0)
        {
            return;
        }

        const pad = this.input.gamepad.getPad(0);

        if (pad.axes.length)
        {
            const axisH = pad.axes[0].getValue();
            const axisV = pad.axes[1].getValue();

            this.sprite.x += 4 * axisH;
            this.sprite.y += 4 * axisV;

            this.sprite.flipX = (axisH > 0);
        }
    }
}

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    input: {
        gamepad: true
    },
    scene: Example
};

const game = new Phaser.Game(config);

Основы: Настройка проекта и загрузка ассетов

Всё начинается с настройки сцены и загрузки ресурсов. Класс Example расширяет Phaser.Scene. В методе preload мы устанавливаем базовый URL для загрузки и указываем изображения фона и спрайта.

this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.load.image('sky', 'assets/skies/lightblue.png');
this.load.image('elephant', 'assets/sprites/elephant.png');

В методе create мы добавляем фоновое изображение в начало координат (левый верхний угол) и создаём спрайт слона в центре экрана, сохраняя ссылку на него в свойство this.sprite для дальнейшего управления.

this.add.image(0, 0, 'sky').setOrigin(0);
this.sprite = this.add.sprite(400, 300, 'elephant');

Ключевой шаг: Активация геймпада в конфигурации

Чтобы Phaser начал слушать события геймпада, необходимо явно включить эту опцию в объекте конфигурации игры. Это делается через свойство input.gamepad.

const config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    input: {
        gamepad: true // Включаем поддержку геймпадов
    },
    scene: Example
};

Без этой настройки система ввода this.input.gamepad будет недоступна. После этого можно создавать экземпляр игры new Phaser.Game(config).

Проверка подключения и получение устройства

Перед работой с геймпадом необходимо убедиться, что он подключён и активирован (пользователь мог нажать кнопку на нём). В Phaser это делается через свойство this.input.gamepad.total.

if (this.input.gamepad.total === 0)
{
    return;
}

Если геймпадов нет, мы выходим из метода update, чтобы избежать ошибок. Для получения ссылки на первый подключённый геймпад используется метод this.input.gamepad.getPad(0).

const pad = this.input.gamepad.getPad(0);

Чтение значений осей и управление спрайтом

Самый интересный этап — работа с осями (аналоговыми стиками). У геймпада pad есть массив axes. Индекс `0обычно соответствует горизонтальной оси левого стика, индекс1` — вертикальной.

if (pad.axes.length)
{
    const axisH = pad.axes[0].getValue();
    const axisV = pad.axes[1].getValue();

Метод getValue() возвращает число от -1 до `1. Например, если стик полностью отклонён влево,axisHбудет равен-1, если вправо —1, в нейтральном положении —0`. Эти значения мы используем для движения и отражения спрайта.

this.sprite.x += 4 * axisH;
this.sprite.y += 4 * axisV;
this.sprite.flipX = (axisH > 0);

Умножая значение оси на коэффициент `4, мы задаём скорость перемещения. Спрайт будет двигаться быстрее, если сильнее отклонить стик. Выражение(axisH > 0)` проверяет, направлен ли стик вправо, и соответственно отражает спрайт по горизонтали.

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

Теперь вы умеете подключать геймпад и использовать его оси для плавного управления объектами в Phaser. Это открывает путь к созданию более динамичного и комфортного геймплея. Для экспериментов попробуйте изменить коэффициент скорости, добавить инерцию движения, привязать к осям другие действия (например, вращение спрайта) или обработать оси других геймпадов (например, правого стика через индексы `2и3`).