马宁的嵌入式开发研究

Windows Phone, XNA, Windows Embedded, Windows Mobile
posts - 84, comments - 752, trackbacks - 17, articles - 0

导航

公告

OpenXLive的多语言支持

Posted on 2012-07-19 09:05 马宁 阅读(...) 评论(...) 编辑 收藏

作者:马宁

OpenXLive SDK 0.9.9下载地址:

http://developer.openxlive.net/sdk/download/

 

OpenXLIve从0.9.9.0版本开始,提供了对简体中文(zh-CN)、繁体中文(zh-TW)的支持。本次主题将介绍如何使OpenXLive显示简体或繁体中文,以及如何通过自定义语言资源包使OpenXLive显示Windows Phone支持的其他语言。

如何更改OpenXLive的显示语言

OpenXLive目前支持3种语言的显示,英语(en-US)、简体中文(zh-CN)和繁体中文(zh-TW)。由于OpenXLive默认显示的是英语(en-US),所有本次主题只介绍如何显示简体中文(zh-CN)和繁体中文(zh-TW)。在了解本主题之前,你应该了解一下Windows Phone全球化和本地化的相关知识,请参阅如下链接http://msdn.microsoft.com/en-us/library/ff637522(v=vs.92)

首先,您需要安装最新版本的OpenXLive SDK,安装前请先卸载旧的版本。您可以在下面的网址中获得OpenXLive SDK的最新版本:http://developer.openxlive.com/

为新建程序设置OpenXLive的显示语言

先介绍新建OpenXLive游戏的时候,如何通过向导选择要显示的语言,请先确保安装最新版OpenXLive SDK。

打开Visual Studio 2010,在Visual Studio 2010的菜单中选择”File” – “New” - “Project”,打开New Project的对话框,选择任意一个OpenXLive游戏模板,本次以OpenXLive Game 为例,输入游戏工程的名称,点击OK。

clip_image002[4]

 

你将会看到如下对话框,

clip_image004[4]

 

在下拉列表中选择要显示的语言,假设我们选择第二项简体中文,点击OK,开始创建OpenXLive游戏工程,工程创建完成后在工程中填入Application Secret Key,然后编译并运行。此时OpenXLive显示的将会是中文简体(zh-CN),效果如下:

clip_image006[4]

 

至此,新建OpenXLive 游戏是通过向导选择显示提供的语言就完成了,非常简单。下面将介绍如何更改已有OpenXLive游戏的显示语言

如何更改已有OpenXLive游戏的显示语言

打开一个已有的OpenXLive游戏工程,首先你需要移除旧版本的OpenXLive的引用。如果是XNA游戏,你需要移除对OpenXLive.dll和OpenXLive.Form.dll的引用。如果是Silverlight游戏,

你需要移除对OpenXLive.dll和OpenXLive.Silverlight.dll的引用。然后添加对新版本的引用。以一个OpenXLive的XNA游戏为例,在添加引用对话框中,选中.NET选项卡,找到并选中OpenXLive.dll、OpenXLive.Font.dll和OpenXLive.Form.dll。

clip_image008[4]

 

如果在.NET选项卡中找不到以上三个dll文件,你可以通过浏览选项卡,在OpenXLiveSDK安装目录下的.\Bin\XNA文件夹下找到(默认应该在C:\Program Files (x86)\Fulcrum Mobile Networks Inc\OpenXLiveSDK\Bin\XNA)。然后点击OK按钮添加引用。

clip_image010[4]

 

到目前为止添加新版本的OpenXLive引用已经完成,如果你现在编译并运行程序,显示的将还是英文(en-US)界面。我们的目的是让OpenXLive显示简体中文(zh-CN)或者繁体中文(zh-TW),你还需要如下设置。

 

首先在“解决方案资源管理器”中,选择游戏项目并右键,选择Unload Project

clip_image012[4]

 

然后再右键该项目,选择Edit <Project File>。此时,项目的csproj文件将会被打开,找到<SupportedCultures>标记,

 

clip_image013[4]

 

并添加程序需要支持的区域性(语言)的名称,如果支持简体中文,则按如下方式更新此标记:[MN2]

<SupportedCultures>zh-CN</SupportedCultures>。如果支持繁体中文,则如下:

<SupportedCultures>zh-TW</SupportedCultures>。如果支持多个语言应该用分号隔开,例如同时支持简体中文和繁体中文,则如下:

<SupportedCultures>zh-CN;zh-TW</SupportedCultures>。

 

clip_image014[4]

 

Windows Phone 区域性和语言支持中所述,你必须要输入正确的区域性/语言名称。

修改完成之后保存并关闭该文件,然后右键项目点击Reload Project重新加载项目。

到目前为止,游戏支持显示的语言已经设置好了,我们还需要指定程序的CurrentUICulture属性为刚才设置的<SupportedCultures>标记中的语言。

打开游戏Game类,在构造函数中添加如下代码:

System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN");

如果<SupportedCultures>标记中设置的是繁体中文即:

<SupportedCultures>zh-TW</SupportedCultures>

代码应该如下:

System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-TW");

了解更多有关CultureInfo类的信息,请参阅

http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo(v=VS.95).aspx

现在,你可以编译并运行程序了,你将会看到OpenXLive已经正确显示出了你指定的语言

 

clip_image016[4]

自定义语言包并正确显示

本主题将介绍如何制作自己的语言包并让OpenXLive正确显示。为了使开发者更容易创建自己的语言包,我们提供了制作语言包的模板。

打开Visual Studio 2010,在Visual Studio 2010的菜单中选择”File” – “New” - “Project”,打开New Project的对话框,选择OpenXLive Game Language Pack或者OpenXLive Silverlight Game Language Pack模板,你也可以通过在搜索框中输入OpenXLive 进行查找,本次以OpenXLive Game Language Pack为例创建一个OpenXLive XNA 游戏的语言包,输入游戏工程的名称,点击OK。

clip_image018[4]

 

你将会看到如下对话框:

clip_image020[4]

 

在文本框中输入该语言包对应的区域性代码,注意:你必须输入正确的区域性代码,你可以点击文本框上的链接查看Windows Phone支持的显示语言对应的区域性代码。我们此次创建一个捷克语(捷克共和国)的语言包,在文本框中输入cs-CZ,点击OK。

clip_image022[4]

 

你会看到项目包含3个刚才输入的cs-CZ区域性代码的资源文件,其中AppResources.cs-CZ.resx和Strings.cs-CZ.resx为OpenXLive所有界面的的显示文字的资源文件,Fonts.cs-CZ.resx为XNA字体资源文件,若果你创建的是OpenXLive Silverlight Game Language Pack项目,则不包含Fonts.cs-CZ.resx文件,你需要将所有AppResources.cs-CZ.resx和Strings.cs-CZ.resx中的Value值对应的英文翻译为指定的语言,注意:请不要更改Name值中的任何字符串。

我们选择的是捷克语,所以应翻译为捷克语。翻译部分不再本主题的范围内,为了能够看出最终的效果,我们只将AppResources.cs-CZ.resx中Name为LobbyAchievements对应的Value值Achievements改为úspěchy,点击保存。LobbyAchievements对应游戏中心中成就按钮的显示文字。

clip_image024[4]

 

接下来我们还需要添加对应的字体文件,以使XNA能够显示我们指定的语言。在XNA中,除了英语外,如果您想正确显示其他语言,就需要首先创建一个SpriteFont对象,然后将需要支持的语言加入其中,编译之后,SpriteFont会成为一个xnb文件,我们只需要将这个xnb文件作为资源文件加入我们的工程即可。

有关如何使XNA显示其他字符[MN3]稍后将会详细介绍。 加入字体文件的步骤如下:

打开Fonts.cs-CZ.resx文件将资源类型有Strings切换到Files

clip_image026[4]

 

然后点击Add Resource添加已经生成好的字体(.xnb)文件,为了使其与OpenXLive风格保持一致,建议字体格式如下:

<FontName>Microsoft YaHei</FontName>

<Size>28</Size>

<DefaultCharacter>□</DefaultCharacter>

注意:添加好字体文件(.xnb)后,您还需要将名称改为MainFont

clip_image028[4]

 

最后编译我们的资源文件。在项目的输出目录里会看到有一个以该语言区域性代码命名的文件夹,

clip_image029[4]

我们将该文件夹拷贝到OpenXLiveSDK安装目录下的.\Bin\XNA文件夹下,(默认应该在C:\Program Files (x86)\Fulcrum Mobile Networks Inc\OpenXLiveSDK\Bin\XNA)若果你创建的是OpenXLive Silverlight Game Resource项目,则应该拷贝到.\Bin\Silverlight目录下

clip_image030[4]

注意,请不要拷贝OpenXLive.Font.dll,

到目前为止,我们的资源文件就创建好了,正如前面更改OpenXLive显示语言中介绍的,你只需要在项目中添加对该捷克语言的支持,并将CurrentUICulture设置为cs-CZ即可:

<SupportedCultures>cs-CZ</SupportedCultures>

System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("cs-CZ");

重新编译并运行你的OpenXLive游戏,切换到游戏中心,你会看到成就按钮显示的文字已经是刚才修改过的了。

 

clip_image032[4]

如何扩展Font Description Processor以支持附加字符

首先,我们在VS 2010的Solution Explorer中找到WindowsPhoneGame1Content项目,右键菜单点击“Add”-“New Folder”,将新文件夹命名为Font,然后在Font上右键点击,选择“Add”-“New Item”,然后在对话框中选择创建“Sprite Font”,将字体文件命名为StartFont。

clip_image034[4]

在Solution Explorer中双击StartFont.spritefont文件,我们会打开一个XML文件,我们省去XML注释部分:

<?xml version="1.0" encoding="utf-8"?>

<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">

<Asset Type="Graphics:FontDescription">

<FontName>Segoe UI Mono</FontName>

<Size>14</Size>

<Spacing>0</Spacing>

<UseKerning>true</UseKerning>

<Style>Regular</Style>

<DefaultCharacter>*</DefaultCharacter> 

<CharacterRegions>

<CharacterRegion>

<Start>&#32;</Start>

<End>&#126;</End>

</CharacterRegion>

</CharacterRegions>

</Asset>

</XnaContent>

按照XML的注释,我们可以很容易的了解每一项的功能,只看高亮部分:FontName,字体的名称;Size,字体的大小;Style,指定字体是否为粗体、斜体等;CharacterRegion,字体区间,目前的设置为只显示ASCII字体。这一点也是非常适合游戏开发的,游戏没有必要提供完整的字符集支持。

接下来就是绘制代码了,首先在类中增加SpriteFont的变量:

public class Game1 : Microsoft.Xna.Framework. Game

{ 

GraphicsDeviceManager graphics;

SpriteBatch spriteBatch;

SpriteFont StartFont;

SpriteFont YaheiFont;

static string Text = "";

我们还增加了一个Text,可以用这个变量从SIP软键盘中获取用户输入的字符串。然后是LoadContent函数:

/// </summary>

protected override void LoadContent()

{

// Create a new SpriteBatch, which can be used to draw textures.

spriteBatch = new SpriteBatch(GraphicsDevice);

// TODO: use this.Content to load your game content here

StartFont = Content.Load<SpriteFont>(@"Font\StartFont");

YaheiFont = Content.Load<SpriteFont>(@"Font\Yahei");

}

请大家注意字体文件的路径:将Content资源放到另外一个DLL里可以方便游戏替换资源,而路径方面,只需要将Folder指定对就可以了。这里顺便把中文微软雅黑字体也加了上了。因为要获取SIP的输入,所以还要修改 Update方法:

protected override void Update(GameTime gameTime)

{

// Allows the game to exit

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)

this.Exit();

// TODO: Add your update logic here

if (Text == "" && !Guide.IsVisible)

Guide.BeginShowKeyboardInput(PlayerIndex.One,

"Here's your Keyboard", "Type something...",

"",

new AsyncCallback(GetTypedChars),

null);

base.Update(gameTime);

}

private static void GetTypedChars(IAsyncResult asynchronousResult)

{

Text = Guide.EndShowKeyboardInput(asynchronousResult);

Debug.WriteLine(Text);

}

我们修改了update方法,只有Text为空时,SIP才会弹出,SIP部分的代码上次已经说过了。最后一部分就是绘制Draw函数了:

protected override void Draw(GameTime gameTime)

{

GraphicsDevice.Clear(Color.White);

// TODO: Add your drawing code here

spriteBatch.Begin();

spriteBatch.DrawString(StartFont, Text, new Vector2(10, 10), Color.Black);

//spriteBatch.DrawString(StartFont, "中国", new Vector2(10, 50), Color.Black);

spriteBatch.End();

base.Draw(gameTime);

}

运行程序,会首先实现一个输入法对话框,输入”Hello,xna”之后,会显示下面的界面:

clip_image035[4]

 

大家注意到,我将第二个绘制“中国”的DrawString注释掉了,如果不注释掉会怎么样呢?产生一个Exception,因为我们Sprite Font的CharacterRegion只包含了ASCII字符,所以,中文字体显然超过了字符范围。

clip_image036[4]

添加中文支持

 

MSDN上的另一篇文章描述了这个问题:

http://msdn.microsoft.com/en-us/library/bb447751.aspx

我们可以Font Description Processor来添加对于指定字符的支持,而不需要扩大CharacterRegions,让很多无用的字符也被增加到字体文件中来。

首先,我们在Solution Explorer中找到游戏的Project,在本例中,就是WindowsPhoneGame1,右键菜单“Add”-“New Item”,选择“Text File”,命名为messages.txt。双击打开messages.txt,在里边添加游戏中要支持的所有中文字符。因为要使用File.ReadAllText,所以确保文本文件是以’\r’或’\n’结尾。

接下来要创建一个新的Content Processor Project,在Solution Explorer中选择Solution,右键点击”Add”-“New Project”,选择”Content Pipeline Extension Library(4.0)”,命名为FontProcessor。下面是ContentProcessor1.cs中修改后的所有代码:

using System;

using System.Collections.Generic;

using System.Linq;

using Microsoft.Xna.Framework;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Xna.Framework.Content.Pipeline;

using Microsoft.Xna.Framework.Content.Pipeline.Graphics;

using Microsoft.Xna.Framework.Content.Pipeline.Processors;

using System.IO;

using System.ComponentModel;

namespace FontProcessor

{

/// <summary>

/// This class will be instantiated by the XNA Framework Content Pipeline

/// to apply custom processing to content data, converting an object of

/// type TInput to TOutput. The input and output types may be the same if

/// the processor wishes to alter data without changing its type.

///

/// This should be part of a Content Pipeline Extension Library project.

///

/// TODO: change the ContentProcessor attribute to specify the correct

/// display name for this processor.

/// </summary>

[ContentProcessor(DisplayName = "FontProcessor.ContentProcessor1")]

public class ContentProcessor1 : FontDescriptionProcessor

{

public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context)

{

string fullPath = Path.GetFullPath(MessageFile);

context.AddDependency(fullPath);

string letters = File.ReadAllText(fullPath, System.Text.Encoding.UTF8);

foreach (char c in letters)

{

input.Characters.Add(c);

}

return base.Process(input, context);

}

[DefaultValue("messages.txt")]

[DisplayName("Message File")]

[Description("The characters in this file will be automatically added to the font.")]

public string MessageFile

{

get { return messageFile; }

set { messageFile = value; }

}

private string messageFile = @"..\WindowsPhoneGame1\messages.txt";

}

}

 

首先,增加两个引用,用于读取文件:

using System.IO;

using System.ComponentModel;

 

然后增加MessageFile的属性:

[DefaultValue("messages.txt")]

[DisplayName("Message File")]

[Description("The characters in this file will be automatically added to the font.")]

public string MessageFile

{

get { return messageFile; }

set { messageFile = value; }

}

private string messageFile = @"..\WindowsPhoneGame1\messages.txt";

 

请注意其中的文件路径,因为文件包含在WindowsPhoneGame1的目录中,而本工程位于FontProcessor目录中,所以我们要修改其路径,否则会出现文件无法找到的编译错误。因为FontProcessor是在编译时使用的,所以Excepiton都是以编译错误展现出来的。

我们还需要将ContentProcessor1的基类ContentProcessor替换为FontDescriptionProcessor。为messages.txt注册Content Pipeline,增加依赖关系,告诉Content Pipeline,如果messages.txt变化,则字体需要重新编译。最后是读取这个文件,为其中的每一个字符增加字体的支持。另外,确保你的messages.txt文件,采用了UTF-8的编码方式。

完成这些之后,我们要首先编译一下FontProcessor,然后在Solution Explorer中,右键点击WindowsPhoneGame1Content的References目录,选择“Add references”,在Project Tab页中,选择FontProcessor。接下来,在Solution Explorer中,右键点击Project Dependencies,将FontProcessor前的CheckBox选中。

然后,创建一个新的Sprite Font字体,叫做YaheiFont,字体名称为“Microsoft Yahei”,选中yahei.spritefont,在属性页中的Content Processor项中,将“Sprite Font Description - XNA Framework”切换为“FontProcessor.ContentProcessor1”。

clip_image037[4]

 

最后,在游戏中增加雅黑字体,将Game中的绘制函数改为:

protected override void Draw(GameTime gameTime)

{

GraphicsDevice.Clear(Color.White);

// TODO: Add your drawing code here

spriteBatch.Begin();

spriteBatch.DrawString(StartFont, Text, new Vector2(10, 10), Color.Black);

spriteBatch.DrawString(YaheiFont, "中国", new Vector2(10, 50), Color.Black);

spriteBatch.End();

base.Draw(gameTime);

}

最后的效果就是:

clip_image038[4]

多语言版本征集计划

OpenXLive为开发者提供了有限的多语言版本支持,但是我们无法满足开发者对于全世界所有语言版本的需求。所以,我们准备启动“OpenXLive多语言版本征集计划”,如果您通晓一门非英语的语言,并且愿意为OpenXLive开发本地化版本,请将您翻译的语言版本资源文件和SpriteFont文件发信给 support@openxlvie.com。如果您的语言版本通过审核,被OpenXLive采纳,我们将采取下列方法感谢您的贡献:

1. 在Readme文件中,会包含您的名字和您翻译的语言版本;

2. 我们将为您准备一份精美的礼品,通过Amazon快递给您。

最后感谢您对OpenXLive长期以来的支持,如果有任何问题和建议,可以发送邮件到:support@openxlive.com