Всякий раз, когда Minecraft отображает текст в игре, он, вероятно, определяется с помощью объекта Text. Этот пользовательский тип используется вместо String для обеспечения более сложного форматирования, включая цвета, выделение жирным шрифтом, обфускации и событий нажатия (click). Они также обеспечивают легкий доступ в систему перевода, что упрощает перевод любого элемента пользовательского интерфейса в разные языки.
Если вы раньше работали с пакетами данных (датапаками) или функциями, вы можете увидеть параллели с текстовым форматом json, используемым для отображения названий, книг, табличек и другого. Как вы, возможно, догадываетесь, это на самом деле json-представление объекта Text, и его можно преобразовать в Text.Serializer и обратно с помощью Text.Serializer\`.
При создании мода, предпочтительнее создавать свои Text объекты непосредственно в коде, используя перевод, когда это возможно.
Текстовые литералы
Самый простой способ создать объект Text это использовать литерал. По сути это строка которая будет отображена как есть, без форматирования по умолчанию.
Они создаются с помощью методов Text.of и Text.literal, которые действуют немного по-разному. Text.of принимает значения null в себя и возвращает экземпляр класса Text. Text.literal же наоборот не сможет принять значение null, и вернётMutableText являющийся наследуемым классом от Text, который можно легко стилизовать и конкатенировать. Подробнее об этом будет сказано позже.
java
Text literal = Text.of("Hello, world!");
MutableText mutable = Text.literal("Hello, world!");
// Keep in mind that a MutableText can be used as a Text, making this valid:
Text mutableAsText = mutable;1
2
3
4
2
3
4
Переводимый Текст
Когда вы хотите предоставить несколько переводов для одной и той же строчки текста, вы можете использовать метод Text.translatable для ссылки на ключ перевода в любом языковом файле. Если ключ не существует, ключ перевода конвертируется в литерал.
java
Text translatable = Text.translatable("my_mod.text.hello");
// Similarly to literals, translatable text can be easily made mutable.
MutableText mutable = Text.translatable("my_mod.text.bye");1
2
3
4
2
3
4
Файл языка, en_us.json, выглядит как то так:
json
{
"my_mod.text.hello": "Hello!",
"my_mod.text.bye": "Goodbye :("
}1
2
3
4
2
3
4
Если вы хотите иметь возможность использовать переменные в переводе, подобно тому, как сообщения о смерти позволяют вам использовать задействованных игроков и предметы в переводе, вы можете добавить указанные переменные в качестве параметров. Вы можете добавить сколько угодно параметров.
java
Text translatable = Text.translatable("my_mod.text.hello", player.getDisplayName());1
Вы можете ссылаться на эти переменные в переводе следующим образом:
json
{
"my_mod.text.hello": "%1$s said hello!"
}1
2
3
2
3
В игре %1$s будет заменено именем игрока, на которого вы ссылаетесь в коде. Использование player.getDisplayName() приведет к тому, что дополнительная информация об объекте появится во всплывающей подсказке при наведении курсора на имя в сообщении чата, в отличие от использования player.getName(), которое все равно получит имя; однако дополнительные детали не отображаются. Аналогичное можно сделать с itemStacks, используя stack.toHoverableText().
Что касается того, что вообще означает %1$s, все, что вам действительно нужно знать, это то, что это число соответствует переменной, которую вы пытаетесь использовать. Допустим, у вас есть три переменные, которые вы используете.
java
Text translatable = Text.translatable("my_mod.text.whack.item", victim.getDisplayName(), attacker.getDisplayName(), itemStack.toHoverableText());1
Если вы хотите указать, кто в нашем случае является злоумышленником, вы должны использовать %2$s, потому что это вторая переменная, которую мы передали. Аналогично, %3$s относится к itemStack. Перевод с таким количеством дополнительных параметров может выглядеть так:
json
{
"my_mod.text.whack.item": "%1$s was whacked by %2$s using %3$s"
}1
2
3
2
3
Десериализация Текста
Как было упомянуто выше, вы можете сериализовать текст в JSON используя текстовый кодек. Для большей информации об кодеках, посмотрите страницу Codec.
java
Gson gson = new Gson();
MutableText mutable = Text.translatable("my_mod.text.bye");
String json = gson.toJson(TextCodecs.CODEC.encodeStart(JsonOps.INSTANCE, mutable).getOrThrow());1
2
3
2
3
В результате получается JSON, который можно использовать в датапаках, командах и других местах которые принимают JSON формат текста вместо буквального или переводимого текста.
Сериализация Текста
Кроме того, чтобы десериализовать текстовый объект в реальный класс Text, опять же, используйте кодек.
java
String jsonString = "...";
Text deserialized = TextCodecs.CODEC
.decode(JsonOps.INSTANCE, gson.fromJson(jsonString, JsonElement.class))
.getOrThrow()
.getFirst();1
2
3
4
5
2
3
4
5
Форматирование Текста
Вы можете быть знакомы со стандартом форматирования в Minecraft:
Вы можете применить эти стили форматирования, используя перечисление Formatting в классе MutableText:
java
MutableText result = Text.literal("Hello World!")
.formatted(Formatting.AQUA, Formatting.BOLD, Formatting.UNDERLINE);1
2
2
| Цвет | Название | Код в чате | Код для MOTD | HEX-код |
|---|---|---|---|---|
| Чёрный (black) | §0 | \u00A70 | #000000 | |
| Тёмно-синий (dark_blue) | §1 | \u00A71 | #0000AA | |
| Тёмно-зелёный (dark_green) | §2 | \u00A72 | #00AA00 | |
| Тёмно-голубой (dark_aqua) | §3 | \u00A73 | #00AAAA | |
| Тёмно-красный (dark_red) | §4 | \u00A74 | #AA0000 | |
| Тёмно-фиолетовый (dark_purple) | §5 | \u00A75 | #AA00AA | |
| Золотой (gold) | §6 | \u00A76 | #FFAA00 | |
| Серый (gray) | §7 | \u00A77 | #AAAAAA | |
| Тёмно-серый (dark_gray) | §8 | \u00A78 | #555555 | |
| Синий (blue) | §9 | \u00A79 | #5555FF | |
| Зелёный (green) | §a | \u00A7a | #55FF55 | |
| Голубой (aqua) | §b | \u00A7b | #55FFFF | |
| Красный (red) | §c | \u00A7c | #FF5555 | |
| Фиолетовый (light_purple) | §d | \u00A7d | #FF55FF | |
| Жёлтый (yellow) | §e | \u00A7e | #FFFF55 | |
| Белый (white) | §f | \u00A7f | #FFFFFF | |
| Сброс форматирования | §r | |||
| Жирный | §l | |||
| §m | ||||
| Подчёркнутый | §n | |||
| Курсив | §o | |||
| Зашифрованный | §k |


