Cocos2d-X游戏开发(五)

来源:互联网 发布:大数据彩票预测王律强 编辑:程序博客网 时间:2024/06/06 14:17

Cocos2d-X游戏开发

  1. 文本

cocos2dx中有三个类可以添加文本信息:LabelTTF,LabelBMFont,LabelAtlas。

  1. Cocos2d-x中文乱码:

不能显示中文

createWithTTF(title,"fonts/Arial.ttf", 24)        

原因为:字体不是中文字体

解决:将字体文件 simhei.ttf (黑体)拷贝到

资源文件夹的fonts文件夹中:

    //读取菜单数据

    Dictionary *strings =Dictionary::createWithContentsOfFile("menu.xml");

    constchar *title = ((String*)strings->objectForKey("title"))->getCString();

    //添加一个文本

    autolabel =Label::createWithTTF(title,"fonts/simhei.ttf", 24 * 2);

    // 设定文本的位置

    label->setPosition(Vec2(origin.x + visibleSize.width / 2,

        origin.y +visibleSize.height -label->getContentSize().height));

    // 添加文本到图层

    this->addChild(label, 1);

结果:

createWithSystemFont(title,"fonts/Arial.ttf", 24)    可以显示中文

create(title,"Arial", 24)                            可以显示中文

解决这个问题常用的有三种方法:

  1. 通过转换为UTF-8编码来显示。
  • 定义:

char *StartLayer::FontToUTF8(constchar*font) {

    int len = MultiByteToWideChar(CP_ACP, 0,font, -1, NULL, 0);

    wchar_t *wstr =newwchar_t[len + 1];

    memset(wstr, 0, len + 1);

    MultiByteToWideChar(CP_ACP, 0,font, -1, wstr, len);

    len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1,NULL, 0, NULL, NULL);

    char *str =newchar[len + 1];

    memset(str, 0, len + 1);

    WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len,NULL, NULL);

    if (wstr)delete[] wstr;

    return str;

}

  • 使用:

LabelTTF *label =LabelTTF::create(StartLayer::FontToUTF8("新游戏"),"Arial", 24 * 2);

这种方法仅仅依靠代码实现而不不需要额外的设置,但是效果并不是很稳定,容易产生某些错误或者依然乱码,因此不推荐该方法。

  1. 使用iconv库来解决。
  • 定义

首先在创建好的cocos2d-x项目中搜索包含了iconv的文件名,然后把文件iconv.h的路径引入:

#include"cocos2d\external\win32-specific\icon\include\iconv.h"

然后在项目中创建一个GBKToUTF8方法来实现编码的转换:

//编码转换,显示中文

intStartLayer::GBKToUTF8(std::string &gbkStr,constchar*toCode, constchar*formCode) {

    iconv_t iconvH;

    iconvH = iconv_open(formCode,toCode);

    if (iconvH == 0) {

        return -1;

    }

    constchar* strChar =gbkStr.c_str();

    constchar** pin = &strChar;

    size_t strLength =gbkStr.length();

    char *outbuf = (char*)malloc(strLength * 4);

    char *pBuff = outbuf;

    memset(outbuf, 0, strLength * 4);

    size_t outLength = strLength * 4;

    if (-1 ==iconv(iconvH, pin, &strLength, &outbuf, &outLength)) {

        iconv_close(iconvH);

        return -1;

    }

    gbkStr= pBuff;

    iconv_close(iconvH);

    return 0;

}

  • 使用:

std::string str ="新游戏";

    GBKToUTF8(str, "gb2312", "utf-8");

    LabelTTF *label =LabelTTF::create(str.c_str(),"Arial", 24 * 2);

不过Android平台上的Cocos2d-x并没有提供相应的库,这就需要开发者自行将iconv库引入到项目中,然后编译。

  1. 使用解析xml或者json文件来解决。
  • xml方法

<?xmlversion="1.0"encoding="utf-8"?>

<dict>

<key>menustart</key>

<string>新游戏</string>

<key>menuclose</key>

<string>退出</string>

</dict>

在xml文件中,<key>和<string>两个标签要保持一一对应的关系。这样就可以通过对key标签中的内容索引到对应的中文内容,从而显示中文字符。需要注意的是保存此xml文件的时候编码格式要使用UTF-8。

    //创建词典类实例,将xml文件加载到词典中

    auto *chnStrings =Dictionary::createWithContentsOfFile("data.xml");

    //通过xml文件中的key获取value

    constchar *str = ((String*)chnStrings->objectForKey("menustart"))->getCString();

    //创建文本

    LabelTTF *label =LabelTTF::create(str, "Arial", 24 * 2);

  • Json方法
  1. 同样准备一个json文件,命名为data.json

{

"start":"开始游戏",

"setting":"设置",

"exitGame":"退出游戏",

"info":"迅腾伟业",

"restart":"重新开始",

"win":"游戏胜利",

"returnMenu":"返回主菜单",

"bgMusic":"背景音乐",

"effectMusic":"音效音量"

}

  1. 引入头文件:

#include"cocos-ext.h"

#include"json/document.h"

  1. 头文件中定义成员变量:

private:

    rapidjson::Document _doc;

    rapidjson::Value mDataArray;

    void initJsonData(floatdt);

  1. 读取JSON数据:

    //读取JSON

    std::string filePath =FileUtils::getInstance()->fullPathForFilename("data.json");

    std::string contentStr =FileUtils::getInstance()->getStringFromFile(filePath);

    log("%s", contentStr.c_str());

    //读取数据到Document对象

    _doc.Parse<0>(contentStr.c_str());

    //读取start节点值

    std::string str = _doc["start"].GetString();

  1. 结果:

 

  1. TTF类型标签

LabelTTF类是通过TTF字体来实现的字体标签。TTF格式是一种在计算机领域通用的字体格式,可以说是使用最为广泛的文字显示格式。

    //读取数据

    Dictionary *strings =Dictionary::createWithContentsOfFile("menu.xml");

    constchar *title = ((String*)strings->objectForKey("title"))->getCString();

    //添加一个文本

    autolabel =LabelTTF::create(title,"fonts/simhei.ttf", 24 * 2);

    // 设定文本的位置

    label->setPosition(Vec2(origin.x + visibleSize.width / 2,

        origin.y +visibleSize.height -label->getContentSize().height));

    // 添加文本到图层

    this->addChild(label, 1);

LabelTTF类显示静态的标签文本很方便,但是渲染速度相对较慢,并且缺乏灵活性。

  1. BMFont标签

LabelBMFont来自于图片文件,所以其实它的作用就相当于精灵表单,而其中的每一个字符则相当于精灵表单中的单个精灵对象。

    //读取数据

    Dictionary *strings =Dictionary::createWithContentsOfFile("menu.xml");

    constchar *title = ((String*)strings->objectForKey("title"))->getCString();

    autolabel =LabelBMFont::create(title,"test.fnt");

    label->setPosition(Vec2(origin.x + visibleSize.width / 2,

        origin.y +visibleSize.height -label->getContentSize().height));

    //执行runAction动作,2秒后放大3倍

    label->runAction(ScaleBy::create(2.0f, 3.0f));

    this->addChild(label, 1);

LabelBMFont标签提升了文字的绘制速度,所以,它是速度最快的字体类。

结果:

  1. Altas标签

LabelAtlas是使用图片作为文字的一种方式,该类通过plist配置文件的描述来定义。

    //第一个参数:显示的内容:1x,你也许会奇怪为什么是1x,因为使用的png图必须是连续的,

    //因为程序内部建议连续的scall码识别的。9的后一位的":",所以要实现x就得用":"代替。

    //第二个参数:图片的名字

    //第三个参数:每一个数字的宽 与实际图片宽相符合

    //第四个参数:每一个数字的高 与实际图片高相符合

    //每五个参数:开始字符 左右方向

    //1:为1x    ==== 6为6 ==== :为x

    LabelAtlas*label = LabelAtlas::create("1:","nums_font.png", 14, 21, '0');

    label->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2));

    this->addChild(label);

    LabelAtlas*label = LabelAtlas::create("3","num.png", 120, 122, '0');

    label->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2));

    this->addChild(label);

结果:

原创粉丝点击