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

Создание игр для международной аудитории требует поддержки разных направлений письма. Phaser предоставляет встроенные средства для отображения текста справа налево (RTL), что критически важно для языков вроде арабского или персидского. В этой статье разберем, как правильно настраивать RTL-текст, обрабатывать смешанный контент и избегать распространенных ошибок в верстке.

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

Живой запуск

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

Исходный код


class Example extends Phaser.Scene
{
    create ()
    {
        // Simple Sentence with punctuation.
        const str1 = 'این یک آزمایش است.';

        // Few sentences with punctuation and numerals. 
        const str2 = '۱ آزمایش. 2 آزمایش، سه آزمایش & Foo آزمایش!';

        // Needs implicit bidi marks to display correctly.
        const str3 = 'آزمایش برای Foo Ltd. و Bar Inc. باشد که آزموده شود.';

        // Implicit bidi marks added; "Foo Ltd.‎ و Bar Inc.‎"
        const str4 = 'آزمایش برای Foo Ltd.‎ و Bar Inc.‎ باشد که آزموده شود.';

        this.add.text(700, 100, str1, { fontFamily: 'Arial', fontSize: 32, color: '#000000', rtl: true });
        this.add.text(700, 200, str2, { fontFamily: 'Arial', fontSize: 32, color: '#000000', rtl: true });
        this.add.text(700, 300, str3, { fontFamily: 'Arial', fontSize: 32, color: '#000000', rtl: true });
        this.add.text(700, 400, str4, { fontFamily: 'Arial', fontSize: 32, color: '#000000', rtl: true });
    }
}

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

const game = new Phaser.Game(config);

Базовый пример: включение RTL

Для отображения текста справа налево в Phaser используется параметр rtl в конфигурации объекта Text. Установите его в true, и движок автоматически изменит направление текста.

this.add.text(700, 100, 'این یک آزمایش است.', { 
    fontFamily: 'Arial', 
    fontSize: 32, 
    color: '#000000', 
    rtl: true 
});

В этом примере персидское предложение 'Это тест.' будет выровнено по правому краю, а чтение текста начнется справа. Без флага rtl: true символы могут отображаться в неправильном порядке.

Смешанный контент: цифры и пунктуация

Особенность RTL-языков — направление текста может меняться внутри строки при наличии цифр или латинских символов. Phaser корректно обрабатывает такие комбинации благодаря встроенной логике двунаправленного текста (BiDi).

const str2 = '۱ آزمایش. 2 آزمایش، سه آزمایش & Foo آزمایش!';
this.add.text(700, 200, str2, { 
    fontFamily: 'Arial', 
    fontSize: 32, 
    color: '#000000', 
    rtl: true 
});

Здесь персидская цифра '۱', арабская пунктуация и латинские символы 'Foo' автоматически позиционируются согласно правилам BiDi. Движок определяет направление для каждого сегмента текста.

Проблема с точками в аббревиатурах

В RTL-тексте точка после латинской аббревиатуры (например, 'Ltd.') может неправильно повлиять на направление последующего текста. Это происходит из-за алгоритмической обработки границ слов.

const str3 = 'آزمایش برای Foo Ltd. و Bar Inc. باشد که آزموده شود.';
this.add.text(700, 300, str3, { 
    fontFamily: 'Arial', 
    fontSize: 32, 
    color: '#000000', 
    rtl: true 
});

Без дополнительных меток текст после 'Ltd.' может начать неправильное направление. Визуально это выглядит как разрыв в потоке RTL.

Решение: явные метки направления

Для явного указания направления используется символ LRM (Left-to-Right Mark) — невидимый управляющий символ Юникода. Он принудительно задает LTR-направление для конкретного отрезка, изолируя его от влияния RTL-контекста.

const str4 = 'آزمایش برای Foo Ltd.‎ و Bar Inc.‎ باشد که آزموده شود.';
this.add.text(700, 400, str4, { 
    fontFamily: 'Arial', 
    fontSize: 32, 
    color: '#000000', 
    rtl: true 
});

Символ `‎` (код U+200E) добавляется после каждой точки в аббревиатуре. Это гарантирует, что точка воспринимается как конец LTR-сегмента, а последующий RTL-текст продолжается корректно.

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

Phaser обеспечивает надежную базовую поддержку RTL через параметр rtl: true. Для сложных случаев со смешанным контентом используйте управляющие символы Юникода. Экспериментируйте: попробуйте динамически вставлять LRM-метки в пользовательский ввод или создайте систему автоматической расстановки меток для аббревиатур в диалогах игры.