这段时间负责多语言版本重构问题,折腾地焦头烂额的。奉劝各位有些东西一定不能拖,从项目开头就要设计好,什么先实现了再来修改都是鬼话。等到了有4000多个代码文件的时候,你就明白改起来有多蛋疼了。但是问题还是要解决的。根据项目实际情况分析,多语言要修改的地方,主要涉及三部分内容:1.代码里直接写入的中文。2.配置文件里的中文。3.UI素材上位图化的中文。
幸好项目中期我们费了点时间,把资源加载框架逐步迁移到了FlexLite的Dll加载管理库上。隔离了代码里对资源URL的直接引用。加上Dll库本身就是为多语言管理预留好了接口,现在改动起来才比较省力。原理简单说就是:Dll持有一张URL映射表,每个路径都映射到一个字符串key上。代码里只引用这个key通过Dll来获取所有资源。所以当要切换多语言版本时,只要修改这张映射表即可,可让同一个key在不同语言环境下获得不同的资源。这样就能在不修改一行代码的情况下,完成多语言版本的配置和管理。
有了这个前提,所以2和3都可以通过再做一份文件的方式,在Dll里靠配置搞定。而代码里的中文,就要动点脑筋了,我们最后想出的方案是,直接使用中文作为key,翻译结果为value。这个方案可以行,是因为UI上所有文本都使用同一个组件显示的,所以在那个组件里的text属性里注入一个文本翻译接口即可。这样就不用修改代码里的中文。在运行时,中文就会被全部替换成对应的文本内容。
以上的方案已经减少了无数的工作量。但剩下的任务还是艰巨的。因为要想办法提取所有的中文词组,生成一张配置表来完成翻译。以中文为key,翻译结果为value的方式存储。遂用AIR写了个工具遍历代码和配置文件,自动提取里面的中文词组。中文字符的判断方法是:
var charCode:String = text.charCodeAt(i);
if(charCode>=0x4e00&&charCode<=0x9fff)
{
//那么text的第i个字符是中文
}
能够获取中文词组了。但是还要注意个问题,代码里有些地方是通过+号的方式来拼接字符串的。对于拼接字符串,分拆开来在翻译时可能会遇到困难(比如中文到英语)。所以我们这么处理。把key写成类似这样的格式:”{0}获得了{1}个金币”,然后写个函数来替换这个字符串即可:tr(“{0}获得了{1}个金币”,[useName,goldNum]);函数体如下:
/**
* 取得一个文本
* @param key 文字索引,如果库中找不到这个索引则直接使用key
* @param params 替换的参数,用于替换{}中的内容
*/
public function tr(key:String,params:Array=null):String
{
var text:String;
if(textDic[key])
{
text = textDic[key]
}
else
{
text = key;
}
if(params)
{
var length:int = params.length;
for(var i:int = 0;i < length;i++)
{
text = text.replace("{"+i+"}", params[i]);
}
}
return text;
}
幸好还有一个规律,要拼接的字符串,在词组所在的同一行内一般都会有个加号。根据这个规律,我们就能工具来标识出所有需要修改的位置(既有中文又有加号的行)。改成用tr()函数标识的方式。虽然还是要人工修改,但是已经减少了不少工作量了。这样结束后,代码文件里的中文key就都获取了。这部分内容我们翻译完要做成配置表。运行时加载进来,作为tr()函数里引用的textDic的查询内容。
至于配置文件中读取的文本。重新创建一个目录,把配置都复制一份进去,等文本内容翻译完毕,直接用工具替换里面的文本内容。然后把这部分配置的URL也加入Dll的加载项文件里。key保持跟原始的版本一致,当语言属性不同。UI素材的处理同理。
就在我们认为大功告成的时候,嵌入字体却出了问题。因为这次先制作的是台湾繁体中文版。所以对应的嵌入字体也要是繁体中文的。但是这个繁体中文死活嵌入不进去(显示不出来)。查到最后,才发现是字体的问题。网上谷歌了下,还有真假繁体之说。GB是中国的简体汉字,在简体平台可以看到。BIG5是港澳台等通用繁体汉字,在繁体平台可以看到。而我们在网上下载的很多字体文件,都是在制作字体的时候,把简体字直接换成了繁体的。也就是在简体平台可看到的是繁体字的模样,但其内码仍是简体,这种叫假繁体。很不幸,我们下载到的字体是假繁体的。检查方法很简单,打开你的输入法,在Word里输入个简体中文,用这种字体它能直接显示为繁体中文。但是你输入繁体中文,它就不显示了。而我们的文本都是翻译过的繁体内容。所以字都显示不出来了。在网上搜索繁体字体下载时,一般都会写明它的编码,注意下载BIG5而不是GB的就行了。