Вполне нормальное явление, когда игра поддерживает несколько языков.
В этом руководстве я покажу, как можно реализовать локализацию в 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);