一款Silverlight开发的游戏最终发布时无论是部署于网站上或是手机等移动设备中,为能让其拥有最广泛的用户使用群体,我们必须在开发初期就将游戏的本地化实现提上议程。

微软为我们提供的Silverlight原生态本地化解决方案是通过在XAP中嵌入多国语言Resource File来实现,过程比较烦琐且效果差强人意。企业应用中就算多包装几个语言文件进XAP亦无关痛痒;然而一款集成有丰富故事脚本、事件剧情及历史背景(比如《龙与地下城》之类史诗级游戏巨著)Silverlight游戏,将所有语言文件一并打包让用户去下载那绝对是糟糕致极的用户体验。

此时我联想到了传统ASP.NET网站开发中的多国语言支持方式:通过定制语言文件格式,用户可在程序入口处根据自身的语言情况去选择加载所需语言包。接下来的问题是,这个方案能否移植到Silverlight游戏产品中?答案是肯定的。

于是,我再次打开当年那些尘封已久的ASP.NET项目,依葫芦画瓢随便建它个5xml语言文件,嘿嘿:

以我最可爱的母语-简体中文(CN.xml)为例,我的规格设定类似如下结构:

接下来就是在游戏入口处根据用户选择下载指定的语言xml配置文件(在上一节中有详细讲解xml的动态下载及缓存方法):

     Downloader downloader = new Downloader();

     downloader.Completed += (s, e) => {

        if (e.stream != null) {

             Global.PackInfo["Language"] = XElement.Load(e.stream);

        }

        downloader.GetResource(string.Format(Global.WebPath("Language/{0}.xml"), languages[i].Tag.ToString()));

    }

根据原则,此xml下载后即缓存到用户电脑中,因此需要时我们只需通过LINQ2XML即可轻松读取指定代号(Code节点)中的文字内容:

        /// <summary>

        /// 获取语言包中指定代号文字内容

        /// </summary>

        /// <param name="code">代号</param>

        /// <returns>文字内容</returns>

        public static string GetLanguagePackContent(int code) {

            try {

                return PackInfo["Language"].DescendantsAndSelf("Content").Single(X => X.Attribute("Code").Value == code.ToString()).Attribute("value").Value;

            } catch {

                return "????";

            }

        }

    当我们需要某代号文字内容时,通过例如Text = Global.GetLanguagePackContent(code)模式即可获取。

值得一提的是,在GetLanguagePackContent方法中我用了try+ catch目的是在开发过程中我们只需使用一国语言作为标准游戏语言(即测试时只用一个xml语言文件,其他国家语言xml文件可以内容暂时为空或不完全),毕竟游戏中的文字内容是随着开发过程不段增加的,此时假设某特殊时候需要必须性的去测试游戏在多国语言环境下的兼容性,而我们暂时又不想停止手中的工作去先做翻译,那么直接用例如”????”代替未存在或未翻译的文字内容即可;另外,当游戏全部完成时进入多国语言测试阶段,测试人员一旦看到有”????”号的地方立刻就能识别出未翻译或BUG所在而至于导致应用程序错误或游戏崩溃,一举两得:

最后要说的是,每个语言包xml文件下载一次后即会保存于浏览器缓存文件夹中,WebClient在下次被请求下载同一文件时会与下载pngjpg图象文件一样首先搜索浏览器缓存去加载,因此同样达到了绿色动态资源配置的效果,用户体验相当好:

整个解决方案不仅简单而且完全动态,作为Silverlight开发Web网络游戏实现本地化支持再优美不过了。当游戏项目完工时,我们只需将CN.xml文件里的所有文字内容复制到google翻译中,一次性就能得到其他语种毛坯级xml语言文件,然后再请相应的翻译人员花上一小撮时间去修正及整理即可,绝对的快捷、绿色环保,嘿嘿。

最后,关于此方案的小遗憾还是有的:通过此方式实现的语言包动态加载在每次游戏登陆时都需要用户去选择一次语言,当然这并非一定就不正确;比方说一个大学生宿舍里有3位来自不同国家的朋友共用一台电脑,那么他们各自登陆时用到的语言均会不同;然而更多的情况是人手一台,那么这就决定了我们有必要将用户上一次登陆时选择的语言记录下来,而不是每次登陆时都重复一次此项操作,同时在游戏窗口适当的位置放上(例如角落的地方)一个按钮,用户可根据特殊情况下就好比前面说的多国用户共用一台电脑的环境中重新再选择其他语言作为标配。朋友们或许要问了,该如何去实现呢?过程都如此清晰了离解决还远吗?

在线演示地址:http://silverfuture.cn

posted on 2010-06-21 17:33  深蓝色右手  阅读(5118)  评论(12编辑  收藏  举报