diff --git a/content/posts/2023/gamemaker/i18n.md b/content/posts/2023/gamemaker/i18n.md new file mode 100644 index 0000000..3236be2 --- /dev/null +++ b/content/posts/2023/gamemaker/i18n.md @@ -0,0 +1,108 @@ +--- +title: "🔣 Локализация в GameMaker" +date: 2023-01-08T10:26:11+03:00 +draft: true +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); +```