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

Ввод текста — частая механика в играх: от ввода имени игрока до ввода паролей или кодов. Phaser предоставляет мощный API клавиатуры, но прямой обработки текстового ввода, как в HTML-полях, в нем нет. Этот пример показывает, как легко реализовать свою собственную логику захвата клавиш для отображения введенных символов и поддержки удаления (backspace).

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        this.add.text(10, 10, 'Enter your name:', { font: '32px Courier', fill: '#ffffff' });

        const textEntry = this.add.text(10, 50, '', { font: '32px Courier', fill: '#ffff00' });

        this.input.keyboard.on('keydown', event =>
        {
            if (event.keyCode === 8 && textEntry.text.length > 0)
            {
                textEntry.text = textEntry.text.substr(0, textEntry.text.length - 1);
            }
            else if (event.keyCode === 32 || (event.keyCode >= 48 && event.keyCode <= 90))
            {
                textEntry.text += event.key;
            }
        });
    }
}

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

const game = new Phaser.Game(config);

Создание текстовых объектов

Первым делом нам нужны визуальные элементы: статическая подпись и динамическое поле для ввода. В Phaser для этого используется метод this.add.text().

this.add.text(10, 10, 'Enter your name:', { font: '32px Courier', fill: '#ffffff' });

const textEntry = this.add.text(10, 50, '', { font: '32px Courier', fill: '#ffff00' });

Первая строка создает подсказку в координатах (10, 10). Вторая строка создает пустое текстовое поле textEntry, которое будет обновляться при нажатии клавиш. Обратите внимание, что начальный текст — пустая строка.

Подписка на события клавиатуры

Чтобы реагировать на нажатия клавиш, мы используем объект this.input.keyboard. Его метод .on() позволяет слушать глобальное событие 'keydown', которое срабатывает при нажатии любой клавиши.

this.input.keyboard.on('keydown', event =>
{
    // Логика обработки события находится здесь
});

Обработчик получает объект события event, который содержит полезные свойства, такие как keyCode (числовой код клавиши) и key (символьное представление клавиши).

Логика обработки нажатий

Внутри обработчика мы определяем, какую клавишу нажал пользователь, и изменяем текст соответственно.

if (event.keyCode === 8 && textEntry.text.length > 0)
{
    // Клавиша Backspace (код 8)
    textEntry.text = textEntry.text.substr(0, textEntry.text.length - 1);
}
else if (event.keyCode === 32 || (event.keyCode >= 48 && event.keyCode <= 90))
{
    // Клавиша Пробел (код 32) или буквенно-цифровые клавиши (коды 48-90)
    textEntry.text += event.key;
}

Первое условие проверяет нажатие Backspace (код 8) и удаляет последний символ из строки textEntry.text, если строка не пуста. Второе условие добавляет символ к строке: оно реагирует на пробел (код 32) и диапазон кодов от 48 (цифра '0') до 90 (буква 'Z'), что покрывает основные буквы и цифры. Свойство event.key автоматически предоставляет правильный символ с учетом регистра и раскладки.

Ограничения и улучшения примера

Данный пример является базовым. Вот несколько моментов, которые стоит учесть для реального проекта:

* **Регистр и раскладка:** Использование event.key решает проблему регистра (Shift) и базовой раскладки. Однако для поддержки всех языков может потребоваться дополнительная логика. * **Фильтрация символов:** Условие (event.keyCode >= 48 && event.keyCode <= 90) захватывает не только буквы и цифры, но и некоторые знаки препинания (например, символы `:или@на разных раскладках). Для точного контроля используйте проверкуevent.key` на соответствие регулярному выражению. * **Фокус ввода:** В примере поле всегда активно. В игре с несколькими элементами UI нужно управлять фокусом (какое поле сейчас принимает ввод). * **Ограничение длины:** Добавьте проверку максимальной длины строки перед добавлением нового символа.

if (textEntry.text.length < MAX_LENGTH) {
    textEntry.text += event.key;
}

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

С помощью всего нескольких строк кода мы создали функциональное поле для ввода текста в Phaser. Это отличная основа для более сложных систем. Попробуйте расширить пример: добавьте мигающий курсор, поддержку клавиш Enter для подтверждения ввода, звуковые эффекты при печати или маску для ввода пароля (замена символов на '*'). Также поэкспериментируйте с другими событиями клавиатуры, например 'keyup', для реализации залипания клавиш.