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

В Phaser Text-объекты поддерживают отображение текста с направлением справа налево (RTL), что критически важно для локализации игр на арабском, иврите и других языках. Однако, как показывает пример из баг-трекера, при комбинации RTL с фиксированной шириной и отступами может возникать неочевидное поведение с выравниванием. Эта статья поможет вам понять, как работает настройка `rtl: true`, и как избежать проблем с визуальным расположением текста в ваших проектах.

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

Живой запуск

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

Исходный код


function create ()
{
    // RTL without padding
    this.add.text(
        400, 250,
        'יא פרו...',
        {
            fixedWidth: 300, fixedHeight: 80,
            backgroundColor: '#333333',
            rtl: true
        }
    );

    // RTL with lett/right padding
    this.add.text(
        400, 350,
        'יא פרו...',
        {
            fixedWidth: 300, fixedHeight: 80,
            padding: {
                left: 30, right: 30
            },
            backgroundColor: '#333300',
            rtl: true
        }
    );
}

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

var game = new Phaser.Game(config);

Базовое создание RTL-текста

Чтобы создать текстовый объект с направлением справа налево в Phaser, используется метод this.add.text(). Ключевой параметр — свойство rtl в объекте стилей, которое необходимо установить в true.

this.add.text(
    400, 250, // Координаты X, Y
    'יא פרו...', // Текст на иврите
    {
        fixedWidth: 300,
        fixedHeight: 80,
        backgroundColor: '#333333',
        rtl: true // Включаем направление справа налево
    }
);

В этом примере текст "יא פרו..." будет отображаться внутри блока шириной 300 пикселей. Благодаря rtl: true направление текста меняется, и он выравнивается по правому краю заданной области (fixedWidth). Это стандартное и ожидаемое поведение для простых случаев.

Проблема с отступами (padding) и RTL

Сложности начинаются при добавлении внутренних отступов (padding). В исходном коде бага создается второй текстовый объект с теми же параметрами, но с дополнительными полями padding.left и padding.right.

this.add.text(
    400, 350,
    'יא פרו...',
    {
        fixedWidth: 300,
        fixedHeight: 80,
        padding: {
            left: 30,
            right: 30
        },
        backgroundColor: '#333300',
        rtl: true
    }
);

Логично ожидать, что текст начнет отрисовываться от правого края, учитывая rtl, и при этом будет соблюден правый отступ (padding.right). Однако в версии Phaser, к которой относится баг, расчет позиции текста внутри блока при включенном RTL мог некорректно учитывать отступы. Это могло приводить к тому, что текст "прилипал" к краю или смещался не так, как ожидал разработчик. Важно проверять актуальную версию движка, так как подобные проблемы часто исправляются.

Анализ конфигурации сцены

Весь пример выполняется в рамках одной сцены (Scene), которая содержит только функцию create. Это минимальная конфигурация для демонстрации графики.

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    scene: {
        create: create // Функция create определена выше
    }
};

var game = new Phaser.Game(config);

Игра создается с размером холста 800x600. Оба текстовых блока размещены по центру по горизонтали (X=400), но на разной высоте (Y=250 и Y=350), чтобы их можно было сравнить. Использование parent: 'phaser-example' позволяет встроить канвас в HTML-элемент с соответствующим id.

Практические рекомендации по работе с RTL

1. **Тестируйте визуально:** Всегда проверяйте отображение RTL-текста, особенно при использовании fixedWidth и padding. Сравнивайте с LTR-версией (слева направо). 2. **Используйте align:** Для тонкого контроля выравнивания текста внутри блока используйте свойство align в стилях (например, 'right', 'left', 'center'). В комбинации с rtl это может дать нужный результат. 3. **Проверяйте версию Phaser:** Убедитесь, что используете последнюю стабильную версию движка, в которой подобные баги могут быть уже исправлены. 4. **Альтернативный подход — контейнеры:** Если поведение Text объекта непредсказуемо, рассмотрите возможность размещения текста (возможно, без fixedWidth) внутри Container и управляйте позиционированием и отступами на уровне контейнера.

// Пример использования выравнивания
this.add.text(x, y, 'RTL текст', {
    rtl: true,
    fixedWidth: 300,
    align: 'right', // Явное выравнивание по правому краю области
    padding: { left: 20, right: 20 }
});

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

Настройка RTL в Phaser через параметр rtl: true — мощный, но требующий внимания инструмент. Основной вывод: при добавлении фиксированной ширины и отступов обязательно проводите визуальное тестирование. Для экспериментов попробуйте: 1. Сравнить поведение одного и того же текста с rtl: true и rtl: false. 2. Поиграть со свойствами align и padding для достижения идеального расположения. 3. Создать динамический пример, где параметры fixedWidth и padding меняются в реальном времени, чтобы увидеть, как движок пересчитывает layout.