--- title: "🔣 Локализация в GameMaker" date: 2023-01-09T01:53:00+03:00 draft: false tags: [tutorial, gamemaker, gamedev] --- ## Много игроков = много языков Вполне нормальное явление, когда игра поддерживает несколько языков. В этом руководстве я покажу, как можно реализовать локализацию в GameMaker. ## Установка языка игры Чаще всего в играх разработчик делает отдельное меню или селектор в настроках для смены языка. И это хороший подход, так как зачастую перевод игры на родной язык хромает. Бывает, да 😑 В данном руководстве я буду получать язык системы игрока динамически, но ничего не мешает тебе внести насколько правом, чтобы сделать изменение языка из меню настроек. В GameMaker есть функция `os_get_language()`, которая возвращает строку с двухбуквенным кодом языка операционной системы на которой запущена игра. Возвращаемое значение соотвествует стандарту [ISO639](https://ru.wikipedia.org/wiki/ISO_639). В таблице ниже приведены примеры некоторых двухбуквенных кодов языков, определенных стандартом ISO 639: ```text | Язык | Код | |-----------------|-----| | Английский язык | en | | Русский язык | ru | | Немецкий язык | de | | Японский язык | ja | ``` ## Получение значений Я написал функцию `get_l10n_text()`, которая принимает текстовое значение, ищет его в массиве строк и возвращает значение в соответствии с установленным в ОС языком. Полный код функции: ```cpp 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` значение языка установленного в ОС и проверяю, имеется ли перевод для этого языка. Если перевода нет, использую язык по умолчанию. ```cpp var lng = os_get_language(); if (!array_has(strings.locales, lng)) { lng = "en"; } ``` В выражении `if` я использую функцию `array_has()`, которая принимает в качестве первого агрумента структуру, а в качестве второго аргумента значение, которое необходимо в ней найти. Код функции `array_has()`: ```cpp 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; } ``` Далее я получаю значение из структуры и возвращаю его. ```cpp var text_struct = variable_struct_get(strings, text); return variable_struct_get(text_struct, lng); ```