当才开始接触cocos2dx的来讲,要实现中文的显示,那么他们就回到网上查,固然方法也不少。这里就总结几个,而后介绍怎么封装实现国际化。json
先声明一个很重要的内容:xcode
cocos2dx 的label之类(包括全部的字符串,好比CCLog)的建立,须要传入一个const char* 即string,这里指望的是以"UTF-8"的编码形式构成的字符串。也就是运行期间他的数据时UTF-8编码的。缓存
因此不少人直接在vs里面写CClog(“中文”);的时候控制台输出实际上是乱码的,由于vs默认不是使用utf8编码的形式,因此不能直接用的。函数
可是xCode是能够的,CClog(“中文”);在xCode里面输出的就是中文。由于xcode是使用utf8编码。工具
因此咱们要显示中文,测试
解决方案1:把含有中文的文件另存为utf8格式,便可解决(这个我没测试过);this
可是就很麻烦,固然能够把全部的文字定义成变量,放到一个头文件里面,那么要改编码的就只有一个头文件了,这样看起来稍微优雅了点。可是仍是很不爽,不能实现国际化。编码
其实直接把文字写在代码里面是一件很不值得推崇的方式(固然图简便仍是能够的,但你须要知道他之后会带来的麻烦会很大),咱们应该把文字独立出来,不跟咱们的代码参合,就像Android的string.xml同样(是否是一下点醒了你?)。spa
因而解决方案2:.net
咱们把全部的文字写到一个配置文件里面,咱们程序直接根据key就获取到了utf8的文字,无论当前的源文件是否是utf8的格式的,由于他们再也不相干了。请慢慢往下面看。
对于配置文件,我选择json格式(为何选择json,没缘由,就喜欢json,干净利落)。
下面给出例子:
个人json的中文配置文档:
里面就是简单的json格式的配置文档(关于不懂json的,我后面会写一篇json的解析的文章,目前先无论,或者大家也能够用其余的格式,好比xml,这样cocos2dx已经有解析方案了,原理是同样的)。
下面就是咱们json解析和使用的代码了(LFString.h和cpp):
#pragma once
#include <string>
#include "json/json.h"
#include "LFFileUtiles.h"
#include <map>
using namespace std;
/**
* 字符串工具,是中文字符的键值对
*/
class LFStrings
{
public:
static bool init();
static string getValue(string _key);
static bool haveValue(string _key);
private:
static bool parseFile(string relativePath);
static map<string,string> data;
};
------cpp
#include "LFStrings.h"
#define ROOT_PATH "config/"
#define FILE_MAIN "strings.txt"
// 所支持的标签
#define LABLE_KEY "key"
#define LABLE_VALUE "value"
#define LABLE_INCLUDE "include"
map<string,string> LFStrings::data;
// 用于缓存已经解析了的文件
static map<string,int> paresedFile;
bool LFStrings::init()
{
data.clear();
paresedFile.clear();
return parseFile(FILE_MAIN);
}
bool LFStrings::parseFile(string relativePath)
{
// 看是否已经解析过了
if (paresedFile.find(relativePath) != paresedFile.end())
{
CCLog("Waring : %s --> file[%s] is pared over before or is in parsing now ,do you include it again???",__FUNCTION__,relativePath.c_str());
return true;
}
paresedFile.insert(pair<string, int>(relativePath,0));
string path = string(ROOT_PATH)+relativePath;
CCLog("%s parsing file [%s] ....",__FUNCTION__,path.c_str());
Json::Reader reader;
Json::Value root;
unsigned long size;
const char* doc = LFFileUtiles::getLFFileUtiles()->readResourceFile(path,&size);
if (size == 0)
{
CCLog("%s ----> file [%s] have no content.",__FUNCTION__,path.c_str());
return true;
}
if (doc == NULL)
{
CCLog("%s ----> doc is NULL , open Error!",__FUNCTION__,path.c_str());
return false;
}
if (!reader.parse(doc,root))
{
CCLog("%s ----> reader.parse failed! [%s]",__FUNCTION__,path.c_str());
CCLog(doc);
delete [] doc;
CCAssert(false,"");
return false;
}
//CCLog(doc);
Json::Value _strings= root["strings"];
if (!_strings.isNull() && _strings.isArray())
{
int _stringNum = _strings.size();
for (int i=0;i<_stringNum;i++)
{
Json::Value onePair = _strings[i];
// 校验
if(!onePair[LABLE_KEY].isNull() && onePair[LABLE_VALUE].isNull())
{
CCLog("Error : %s there is no %s for %s [%s]",__FUNCTION__,LABLE_VALUE,LABLE_KEY,onePair[LABLE_KEY].asCString());
CCAssert(false,"key 和 value 没有配对");
continue;
}
if(!onePair[LABLE_VALUE].isNull() && onePair[LABLE_KEY].isNull())
{
CCLog("Error : %s there is no %s for %s [%s]",__FUNCTION__,LABLE_KEY,LABLE_VALUE,onePair[LABLE_VALUE].asCString());
CCAssert(false,"key 和 value 没有配对");
continue;
}
//有include
if (!onePair[LABLE_INCLUDE].isNull())
{
string file = onePair[LABLE_INCLUDE].asString();
if (!parseFile(file))
{
CCLog("Error : %s parse file %s faild",__FUNCTION__,file.c_str());
return false;
}
}
// 解析键值对
if (!onePair[LABLE_KEY].isNull() && !onePair[LABLE_VALUE].isNull())
{
string _key = onePair[LABLE_KEY].asString();
string _value = onePair[LABLE_VALUE].asString();
if (haveValue(_key))
{
CCLog("Waring : %s --> the key [%s] in file[%s] is already used before,we will ignore this key and value[%s]!",__FUNCTION__,_key.c_str(),path.c_str(),_value.c_str());
continue;
}
data.insert(pair<string, string>(_key,_value));
}
}
}
return true;
}
string LFStrings::getValue(string _key)
{
map<string, string>::iterator iter;
//若是map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器;
iter = data.find(_key);
if(iter != data.end())
{
return iter->second;
}
CCLog("Waring : LFStrings::getValue --> _key[%s] is not found!",_key.c_str());
return "";
}
bool LFStrings::haveValue(string _key)
{
map<string, string>::iterator iter;
//若是map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器;
iter = data.find(_key);
return iter != data.end();
}
使用方法很简单,游戏启动的时候调用:
// 初始化
LFStrings::init();
他就会找Resource下面的config下面的string.txt文件,进行初始化。
每次要用中文的时候直接:LFStrings::getValue(“biaoti”);// 取得标题字符串
便可。这样就轻松实现中文了,之后直接配置,修改就是了。
最后一个问题,怎么实现国际化:
需呀稍微修改下LFStrings类,直接让他解析不一样的配置文件就是了,其余的全部代码就不用改。就能够实现语言的动态切换了。
明白了吧?