有时候我们做的游戏不仅仅发布在国内市场,有时候也需要发布在国际市场,这时候我们至少需要中英2套菜单来供不同的玩家使用,毕竟中文不是每个人都能看懂。
Libgdx中提供了I18NBundle来供我们使用,I18NBundle提供了一套机制可以使我们从属性(properties)文件中加载资源, 属性文件中的资源是以”name”和”values”的形式存在的,而且资源最好有一个父文件,这样防止资源丢失时,可以使用父文件中的值:
通过上面图片可以看出string.properties就是父文件,另外2个分别对应中文文件和英文文件
1. 由于默认的BitmapFont不支持中文,因此必须自己重新创建一个.fnt文件,文件中必须包含Properties中的所有汉字,具体看前面博客。
2. 在用Eclipse创建properties文件时默认的编码不是**UTF-8**,这时显示的不是中文,切换编码到**UTF-8**就OK了
I18NBundle 常用方法说明:
1. static I18NBundle createBundle(FileHandle baseFileHandle, java.util.Locale locale) 根据properties文件和国家编码来创建I18NBundle对象
2. java.lang.String format(java.lang.String key, java.lang.Object… args) 格式化获取的values
3. java.lang.String get(java.lang.String key) 根据key来获取values
下面来看代码,代码中也有说明:
public class LocalizationTest extends ApplicationAdapter {
SpriteBatch sb;
Vector3 touch;
OrthographicCamera cam;
private BitmapFont font;
private LanguageManager lm;
private FileHandle enFileHandle, cnFileHandle;
private String gameTitle, gameBegin, gameHelp;
@Override
public void create() {
sb = new SpriteBatch();
touch = new Vector3();
cam = new OrthographicCamera(640, 480);
cam.position.set(320, 240, 0);
cam.update();
/**
* 默认字体里面不支持中文,需要自己使用Hiero来创造字体文件
*/
font = new BitmapFont(Gdx.files.internal("font/in.fnt"));
lm = new LanguageManager(); // 初始化语言管理器,加载语言
enFileHandle = Gdx.files.internal("strings_en_GB");
cnFileHandle = Gdx.files.internal("strings_zh_CN");
lm.loadLanguage("english", enFileHandle, Locale.UK); // 加载文字文件
lm.loadLanguage("chinese", cnFileHandle, Locale.CHINA);
if (lm.getCurrentLanguage().equals("zh_CN")) {
lm.setCurrentLanguage("chinese");
} else {
lm.setCurrentLanguage("english");
}
initializeText();
}
private void initializeText() {
I18NBundle b = lm.getCurrentBundle();
gameTitle = b.get("gameTitle"); // 根据key来获取对应的values
gameBegin = b.format("gameBegin", 81); // 先根据key来获取对应的values值,再格式化语言
gameHelp = b.get("gameHelp");
}
private void translate() {
if(lm.getCurrentLanguage().equals("chinese"))
lm.setCurrentLanguage("english");
else
lm.setCurrentLanguage("chinese");
initializeText();
}
@Override
public void render() {
Gdx.gl.glClearColor(0.39f, 0.58f, 0.92f, 1.0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
sb.setProjectionMatrix(cam.combined);
sb.begin();
font.draw(sb, gameTitle, 60, 260);
font.draw(sb, gameBegin, 60, 160);
font.draw(sb, gameHelp, 60, 60);
font.draw(sb, "Touch Up Translate", 320, 240);
sb.end();
if (Gdx.input.justTouched()) {
touch.set(Gdx.input.getX(), Gdx.input.getY(), 0);
cam.unproject(touch);
if (320 < touch.x && touch.x< 640 && // 点击第一象限来切换语言
240 < touch.y && touch.y< 480) {
translate();
}
}
}
@Override
public void dispose() {
sb.dispose();
font.dispose();
}
public class LanguageManager {
private ObjectMap<String, I18NBundle> languages;
private String currentLanguage;
public LanguageManager() {
languages = new ObjectMap<String, I18NBundle>();
/*此处获取的默认语言格式,和后面保存的语言格式不统一,在正式使用时会做一个转换
* 或者语言和I18NBundle对象不保存在ObjectMap里面,用别的数据结构,此处不考虑这种情况
* */
currentLanguage = Locale.getDefault().toString();
}
public void loadLanguages(String name, I18NBundle bundle) {
if (name != null && !name.isEmpty() && bundle != null)
languages.put(name.toLowerCase(), bundle);
}
/**
* 储存语言及其对应的I18NBundle对象,方便以后获取
* @param name 语言名称
* @param fileHandle properties文件对象
* @param locale 国家编码
*/
public void loadLanguage(String name, FileHandle fileHandle, Locale locale) {
if (name != null && !name.isEmpty() && fileHandle != null && locale != null)
languages.put(name.toLowerCase(), I18NBundle.createBundle(fileHandle, locale));
}
public void loadLanguage(String name, FileHandle fileHandle) {
if (name != null && !name.isEmpty() && fileHandle != null)
languages.put(name.toLowerCase(), I18NBundle.createBundle(fileHandle));
}
public void removeLanguage(String name, I18NBundle bundle) {
if (name != null && !name.isEmpty() && bundle != null)
languages.remove(name.toLowerCase());
}
public void setCurrentLanguage(String name) {
if (languages.containsKey(name.toLowerCase()))
currentLanguage = name;
}
public String getCurrentLanguage() {
System.out.println("currentLanguage: " + currentLanguage);
return currentLanguage;
}
public I18NBundle getCurrentBundle() {
return languages.get(currentLanguage);
}
}
}
原文:http://blog.csdn.net/zqiang_55/article/details/51925547