Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Нужен совет опытного флешера по мультиязычности. (http://www.flasher.ru/forum/showthread.php?t=180856)

searinox 10.06.2012 00:35

Нужен совет опытного флешера по мультиязычности.
 
Есть клиентское приложение, в нём необходимо реализовать мультиязычность (т.е. при выборе юзером определенного языка, во всех необходимых местах заменять тексты на дефалтном языке, на тексты на необходимом.
На данный момент существует такая система:
1. Есть ХML в котором содержатся тексты на необходимом языке. Например текстфилду который в кнопке выхода ("exit_btn_text") соответствует текст "Exit" ну и т.д.
2. Есть класс который парсит этот ХML и меняет текст в необходимом элементе интерфейса.
3. В управляющем классе замена языков происходит при загрузке приложения и при выборе юзером необходимого языка в опциях.

Вопрос следующего характера - как всю эту *****систему сделать более правильной, эргономичной и вообще как нормальные люди реализовывают такие вещи?

Psycho Tiger 10.06.2012 01:10

Пара ключ-значение.
Например, можно сделать класс View, который содержит методы работы с тем, что может понадобиться вью.
Например, getResource, для загрузки динамического контента или getLocaleText, возвращающий текст сразу в нужной локали.
Т.е. локаль устанавливается где-то наверху, а элементы отображения делают что-то вроде:
Код AS3:

//ru
super.getLocaleText('inventory.close'); //returns Закрыть инвентарь
 
//en
super.getLocaleText('inventory.close'); //returns Close inventory


searinox 10.06.2012 01:33

То есть ты предлагаешь написать класс который самостоятельно разыменовывает ВСЕ элементы интерфейса, а сама именовка происходит для каждого элемента по его названию?
т.е. код метода getLocaleText() будет какой-то такой?
Код AS3:

function getLocaleText(value:String):String{
switch (value){
 
 case "accept_btn":
 //вернуть необходимый текст
 break;
 
 case "cancel_btn":
//вернуть необходимый текст
 break;
 
 case "exit_btn":
//вернуть необходимый текст
 break;
 
 }
}


Psycho Tiger 10.06.2012 09:25

Реализаций может быть много. Я бы хранил тексты в разных xml файлах, типа en.xml, ru.xml и т.далее, а сам getLocaleText бы возвращал значение из этого xml. Например, interface.close - это тег interface, внутри тег close.

Korchy 10.06.2012 09:57

Я загружаю из базы список текстов. А в флешке запихиваю все это в массив и где нужно вызываю через класс-обертку над массивом.
Что-то вроде:
Button.Text = TextDictionary.Text(1);
В зависимости от выбранного пользователем языка в массиве в TextDictionary в первом элементе будет лежать или "Выход" для русского или "Exit" для английского языка.
Не знаю на сколько это правильно и экономично. Пока работает :)

kackbip 10.06.2012 10:46

Обращение к элементам по номеру непоказательно. Лучше использовать говорящие индексы, константы или как psycho tiger написал - теги xml.

Inet_PC 10.06.2012 12:37

Работает не трожь, не?

-De- 10.06.2012 16:02

Да, по тегам из xml или ключам из Object вытягивать строку. Что ещё. Для больших приложений удобнее сделать двухуровневую систему, т.е.
Код AS3:

function getLocaleText(group:String, key:String):String

использовать например
Код AS3:

playButton.setText(getLocaleText("mainMenu", "play"));

Почему ещё это всплывает - имеет смысл привязывать строку локализацию не к слову, а к конкретному месту. Т.е. неправильно: слово "играть" имеет ключ play и везде, где встречается слово играть используется getLocaleText("play"). Правильно: для каждого места, где встречается слово "играть", делается отдельный ключ. Потому что на разных языках там могут быть разные слова и даже на одном языке могут быть различия в регистре ("ИГРАТЬ", "играть", "играть!" и "Играть").
Подумать насчет того, что смена языка вызывает перезапуск приложения (или делается только при самом старте). Потому что смена языка в любом месте в любой момент достаточно сложна в реализации и никому на самом деле не нужна.
Отдельная веселуха (особенно если есть смена языка в любой момент) - строки типа "Убито бобров 7 из 20, спасено деревьев - 7шт.". Не во всех языках удобно и вообще возможно, чтоб 7, 20 и 7 шли именно в таком порядке (лично мне такое встретилось в тексте просто "2 из 3", по-моему на тайском). Потому хороший вариант - написать функцию типа
Код AS3:

function getLocaleTextParametrized(group:String, key:String, paramsArray:Array):String

Которая из строки типа "Убито бобров [1] из [2], спасено деревьев - [1]шт." делала нужную вызовом типа
Код AS3:

getLocaleTextParametrized("statsMenu", "beaverProgress", [7, 20])


expl 10.06.2012 19:30

Код AS3:

getLocaleTextParametrized("statsMenu", "beaverProgress", [7, 20])

У нас такая штуковина, дабы не травмировать мозг запоминанием ключей, количества и назначения праметров для каждого ключа просто генерируется из таблицы с локализацией:

Код AS3:

/** Какой-то текст с {parameter}-ом на ключ some_text */ //<-- это сгенерилось по дефолтному языку локализации -
//чтобы не отвлекаться, не смотреть что значит ключ
public static function some_text(parameter:String):String
{
        return _values["some_text"].replace(/\{parameter\}/g, parameter);// Утрированно
}

Т.е набрал в редакторе в дной колонке ключ - в другой (соответствующей языку) текст - нажал ctl-s - у тебя добавились эти строчки в код и сгенерился файл для загрузки локализации.

Т.е. приведённый текст выглядел бы так:
Код AS3:

Locale.statsMenu_beaverProgress(7, 20);

Для локализации объектов, а не интерфейса, конечно, так делать не надо и не получится, но для них и тучу ключей поддерживать не надо - просто берёшь ключ у игрового объекта и берешь по нему название этого объекта - такой ключ не захардкожен, его нет в коде.

По поводу динамической замены языка - ни разу не приходилось делать (не требовалось), но возможны варианты:
1. Как в fl-компонентах - регистрируем прямо в локализаторе текстовые поля с ключом и при перезагрузке он их обновляет
2. Вручную подписываемся на локализатор во всех окошках и меняем все тексты при событии "изменился язык"
3. Делаем наследника TextField, который уже слушает изенения и сам себя меняет и используем его везде. А если сторонние компоененты используюся? - оборачивать?

Проблемы тут 2:
1. Как везде поменять текст с минимальным количеством кода
2. Размеры, вот незадача, тоже у полей будут меняться и ведь нужно реагировать - менять размеры окон и панелей, или дикий запас пространства оставлять

Вобщем, перечисленные 3 способа справляются с этими задачами с разным успехом.

Партизан 11.06.2012 11:57

Локализация "на лету" у меня решается следующей схемой:
1. XML
Код:

<string id="str_id" ru="" en="" kz="" />
2. Функция в которой регистрируется str_id и текстфилд которому присваевается строка с текущей локалью. Все помещается в хэш-таблицу ключом которой выступает str_id, а значением соответственно текстфилд.
3. При смене локали всем зарегистрированным текстфилдам присваевается соответсвующая новой локали строка.

В общем случае такая схема удобна, проста и при необходимости может легко быть дополнена функционалом. Преимуществом является простая схема подписки на событие смены языка, точнее ее полное отсутствие. Один раз присваеваем значение и забываем про это.
Я честно говоря, пока использовал такой подход только в одном-двух проектах, но думаю, теперь буду постоянно использовать.


Часовой пояс GMT +4, время: 09:39.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.