Blog/content/posts/2023/gamemaker/i18n.md

4.6 KiB
Raw Blame History

title date draft tags
🔣 Локализация в GameMaker 2023-01-09T01:53:00+03:00 false
tutorial
gamemaker
gamedev

Много игроков = много языков

Вполне нормальное явление, когда игра поддерживает несколько языков.
В этом руководстве я покажу, как можно реализовать локализацию в GameMaker.

Установка языка игры

Чаще всего в играх разработчик делает отдельное меню или селектор в настроках для смены языка.

И это хороший подход, так как зачастую перевод игры на родной язык хромает.
Бывает, да 😑

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

В GameMaker есть функция os_get_language(), которая возвращает строку с двухбуквенным кодом языка операционной системы на которой запущена игра. Возвращаемое значение соотвествует стандарту ISO639.

В таблице ниже приведены примеры некоторых двухбуквенных кодов языков, определенных стандартом ISO 639:

| Язык            | Код |
|-----------------|-----|
| Английский язык |  en |
| Русский язык    |  ru |
| Немецкий язык   |  de |
| Японский язык   |  ja |

Получение значений

Я написал функцию get_l10n_text(), которая принимает текстовое значение, ищет его в массиве строк и возвращает значение в соответствии с установленным в ОС языком.

Полный код функции:

function get_l10n_text(text) {
    var strings = {
        locales: ["en", "ru"],
        reset_btn: {
            desc: "The restart button in menu",
            en: "Restart",
            ru: "Играть снова"
        },
        start_btn: { desc: "The start button in menu", en: "Start", ru: "Играть" }
    };

    var lng = os_get_language();

    if (!array_has(strings.locales, lng)) { lng = "en"; }

    var text_struct = variable_struct_get(strings, text);

    return variable_struct_get(text_struct, lng);
}

Разбор кода

Структура strings хранит в себе строки с их переводами а другие языки.

Например reset_btn это кнопка сброса в игре. В коде я вызываю функцию get_l10n_text() используя в качестве аргумента это значение.

Значения en и ru соответствуют переведённым строкам.
Значение desc используется для описания.

Первый делом я присваиваю переменной lng значение языка установленного в ОС и проверяю, имеется ли перевод для этого языка.
Если перевода нет, использую язык по умолчанию.

var lng = os_get_language();
if (!array_has(strings.locales, lng)) { lng = "en"; }

В выражении if я использую функцию array_has(), которая принимает в качестве первого агрумента структуру, а в качестве второго аргумента значение, которое необходимо в ней найти.

Код функции array_has():

function array_has(array_to_search, value_to_find) {
    var search_array = array_to_search;
    var find_value = value_to_find;
    var loop = 0;
    repeat (array_length_1d(search_array)) if (search_array[loop++] == find_value) return true;
    return false;
}

Далее я получаю значение из структуры и возвращаю его.

var text_struct = variable_struct_get(strings, text);
return variable_struct_get(text_struct, lng);