О чем этот пример
При создании игр часто возникает задача реализовать поле ввода текста — будь то имя игрока, чат или ввод команд. Использование BitmapFonts позволяет добавить стилизованные, пиксельные шрифты, сохраняя уникальный визуальный стиль игры. Однако простой ввод текста может сломать интерфейс, если строка выходит за пределы отведённой области. В этой статье мы разберём, как с помощью свойства `setMaxWidth` для BitmapText легко организовать автоматический перенос введённого текста, создав аккуратное и функциональное поле ввода.
Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.
Живой запуск
Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.
Исходный код
class Example extends Phaser.Scene
{
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.fonts = [ 'iceicebaby', 'atari-smooth', 'azo-fire', 'carrier_command', 'vermin', 'chiller', 'clarendon', 'desyrel-pink', 'gem', 'gothic', 'hyperdrive', 'topaz-fill' ]
for (let i = 0; i < this.fonts.length; i++)
{
this.load.bitmapFont(this.fonts[ i ], 'assets/fonts/bitmap/' + this.fonts[ i ] + '.png', 'assets/fonts/bitmap/' + this.fonts[ i ] + '.xml');
}
}
create ()
{
this.add.text(10, 10, 'Enter your name:', { font: '32px Courier', fill: '#ffffff' });
const currentText = [];
const textEntry = this.add.bitmapText(10, 50, 'gem')
.setFontSize(20)
.setMaxWidth(200);
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;
// textEntry.setText([...currentText, event.code].join("") );
}
});
}
}
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Подготовка: загрузка bitmap-шрифтов
Перед использованием bitmap-шрифтов их необходимо загрузить. В методе preload мы определяем массив с именами шрифтов и в цикле загружаем каждый из них. Важно, что для bitmap-шрифта требуется два файла: изображение (.png) с глифами и файл описания (.xml или .fnt), содержащий данные о расположении символов.
preload ()
{
this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
this.fonts = [ 'iceicebaby', 'atari-smooth', 'azo-fire', 'carrier_command', 'vermin', 'chiller', 'clarendon', 'desyrel-pink', 'gem', 'gothic', 'hyperdrive', 'topaz-fill' ]
for (let i = 0; i < this.fonts.length; i++)
{
this.load.bitmapFont(this.fonts[ i ], 'assets/fonts/bitmap/' + this.fonts[ i ] + '.png', 'assets/fonts/bitmap/' + this.fonts[ i ] + '.xml');
}
}
Создание текстового поля с ограничением по ширине
В методе create мы создаём два текстовых объекта. Первый — обычная текстовая подсказка, созданная через this.add.text. Второй, textEntry, — это наше основное поле ввода, созданное как bitmapText. Ключевой момент — вызов метода .setMaxWidth(200). Этот метод устанавливает максимальную ширину, которую может занимать одна строка текста. Если текст превышает эту ширину, он автоматически переносится на новую строку.
create ()
{
this.add.text(10, 10, 'Enter your name:', { font: '32px Courier', fill: '#ffffff' });
const textEntry = this.add.bitmapText(10, 50, 'gem')
.setFontSize(20)
.setMaxWidth(200);
}
Обработка ввода с клавиатуры
Чтобы поле ввода реагировало на клавиши, мы настраиваем слушатель события keydown на клавиатуре. В обработчике проверяем код нажатой клавиши (event.keyCode). Если нажата Backspace (код 8) и в тексте есть символы, мы удаляем последний символ. Если нажата клавиша пробела (код 32) или буквенно-цифровая клавиша (коды от 48 до 90), мы добавляем соответствующий символ из event.key к тексту объекта textEntry.
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;
}
});
При каждом изменении свойства text объекта BitmapText происходит перерисовка. Если включён maxWidth, текст автоматически разбивается на строки, ширина которых не превышает заданное значение.
Конфигурация и запуск игры
Сцена готова, осталось создать конфигурацию игры и её экземпляр. В конфиге мы указываем базовые настройки: тип рендерера, родительский HTML-элемент, размеры холста и ссылку на наш класс сцены.
const config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);
Что попробовать дальше
Использование setMaxWidth для BitmapText — это простой и эффективный способ контролировать отображение динамического текста в интерфейсе. Вы можете экспериментировать: изменить значение maxWidth в реальном времени в зависимости от действий игрока, комбинировать разные bitmap-шрифты для выделения частей текста или создать многострочное поле ввода с прокруткой, отслеживая общую высоту текстового блока.
