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

109 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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);
```