• 分享
  • Cocos2d - x Label 在 Windows 平台中文乱码及读取问题学习笔记教程

  • @ 2025-8-2 18:32:51

Cocos2d - x Label 在 Windows 平台中文乱码及读取问题学习笔记教程

一、前言

在使用 Cocos2d - x 进行 Windows 平台开发时,当我们需要通过 Label 显示中文内容,常常会遇到中文乱码问题,这是由于字符编码、字体支持等多种因素导致的。下面我们就来详细探讨如何解决这些问题,以及正确读取并显示中文。

二、中文乱码问题原因分析

(一)字符编码不匹配

Cocos2d - x 项目在编译和运行过程中,若源文件的编码格式(比如常见的 UTF - 8 、GBK 等)与程序读取和处理字符的编码方式不一致,就会导致中文乱码。例如,源文件是 UTF - 8 编码,而程序在读取字符串并传递给 Label 显示时,按照 GBK 编码去解析,那么中文就无法正确显示。

(二)字体不支持

如果创建 Label 时所使用的字体不包含中文的字形信息,即使字符编码正确,也只能显示出一个个小方块或者乱码。比如使用了一些仅支持英文字符的字体来显示中文,就会出现这种情况。

三、解决中文乱码问题

(一)确保字符编码一致

  1. 设置源文件编码:在 Visual Studio 中,打开包含 Label 相关代码的 .cpp 文件(比如 HelloWorldScene.cpp )。点击 文件 -> 高级保存选项 ,将编码设置为 Unicode (UTF - 8 带签名) - 代码页 65001 ,这样能保证源文件以 UTF - 8 编码保存中文内容。
  2. 设置项目属性:右键点击项目 -> 属性 ,在 配置属性 -> 常规 中,将 字符集 设置为 使用 Unicode 字符集 。这一步是为了让项目在编译和运行时,能正确处理 UTF - 8 编码的字符。

(二)选择支持中文的字体

在创建 Label 时,使用支持中文的字体,比如常见的 “微软雅黑”、“宋体” 等。以下是使用不同方式创建 Label 并设置支持中文字体的示例:

1. 使用系统字体创建支持中文的 Label

#include "HelloWorldScene.h"
#include "cocos2d.h"
USING_NS_CC;

bool HelloWorld::init()
{
    if (!Scene::init())
    {
        return false;
    }

    // 获取窗口可见大小,用于设置 Label 位置
    auto visibleSize = Director::getInstance()->getVisibleSize(); 

    // 使用系统字体创建 Label,这里选择 "微软雅黑" 字体,能支持中文显示
    auto label = Label::createWithSystemFont("你好,世界!", "微软雅黑", 36); 

    // 设置锚点在 Label 中心,方便后续设置位置让 Label 居中
    label->setAnchorPoint(Vec2::ANCHOR_MIDDLE); 

    // 将 Label 设置在屏幕正中心位置
    label->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2)); 

    // 将 Label 添加到当前场景中,这样才能在游戏运行时显示出来
    this->addChild(label); 

    return true;
}

解释createWithSystemFont 方法的第二个参数指定为 “微软雅黑” ,该字体是 Windows 系统自带且支持中文显示的字体,第一个参数传入要显示的中文内容 “你好,世界!”,即可正常显示中文。

2. 使用 TTF 字体创建支持中文的 Label

首先需要准备一个支持中文的 TTF 字体文件,比如 simhei.ttf (黑体 ),将其放到项目的资源目录(假设是 resource 目录 )。

#include "HelloWorldScene.h"
#include "cocos2d.h"
USING_NS_CC;

bool HelloWorld::init()
{
    if (!Scene::init())
    {
        return false;
    }

    auto visibleSize = Director::getInstance()->getVisibleSize(); 

    // 使用 TTF 字体创建 Label,第一个参数是要显示的中文内容,
    // 第二个参数是 TTF 字体文件的路径(这里假设字体文件在 resource 目录下),第三个参数是字体大小
    auto label = Label::createWithTTF("你好,中文 TTF 字体!", "resource/simhei.ttf", 36); 

    label->setAnchorPoint(Vec2::ANCHOR_MIDDLE); 
    label->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2)); 
    this->addChild(label); 

    return true;
}

解释createWithTTF 方法通过指定正确的 TTF 字体文件路径(这里是 resource/simhei.ttf ),确保字体包含中文的字形信息,从而正确显示中文内容。

四、中文读取与显示的拓展应用

(一)从文件中读取中文并显示

有时我们需要从外部文件(比如文本文件 )中读取中文内容,再通过 Label 显示出来。以下是示例代码:

  1. 准备文本文件:在项目的资源目录(假设是 resource 目录 )下创建一个 test.txt 文件,使用 UTF - 8 编码格式,在文件中写入中文内容,例如 “这是从文件中读取的中文” 。
  2. 代码实现读取并显示
#include "HelloWorldScene.h"
#include "cocos2d.h"
#include <fstream> // 用于文件读取的头文件
#include <string>
USING_NS_CC;

bool HelloWorld::init()
{
    if (!Scene::init())
    {
        return false;
    }

    auto visibleSize = Director::getInstance()->getVisibleSize(); 

    std::ifstream file("resource/test.txt"); // 打开文本文件
    if (file.is_open())
    {
        std::string content;
        std::string line;
        while (std::getline(file, line)) // 逐行读取文件内容
        {
            content += line;
        }
        file.close(); // 关闭文件

        // 使用读取到的中文内容创建 Label,这里依旧选择支持中文的字体,比如 "微软雅黑"
        auto label = Label::createWithSystemFont(content.c_str(), "微软雅黑", 36); 

        label->setAnchorPoint(Vec2::ANCHOR_MIDDLE); 
        label->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2)); 
        this->addChild(label); 
    }

    return true;
}

解释:通过 std::ifstream 打开文本文件,利用 std::getline 逐行读取文件内容并拼接,关闭文件后,将读取到的字符串传递给 Label::createWithSystemFont 方法创建 Label 并显示,注意要使用支持中文的字体。

(二)动态更新 Label 的中文内容

在游戏运行过程中,可能需要动态改变 Label 显示的中文内容,示例如下:

#include "HelloWorldScene.h"
#include "cocos2d.h"
USING_NS_CC;

bool HelloWorld::init()
{
    if (!Scene::init())
    {
        return false;
    }

    auto visibleSize = Director::getInstance()->getVisibleSize(); 

    // 初始创建一个 Label
    auto label = Label::createWithSystemFont("初始中文内容", "微软雅黑", 36); 
    label->setAnchorPoint(Vec2::ANCHOR_MIDDLE); 
    label->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2)); 
    this->addChild(label); 

    // 模拟在一定条件下(这里简单设置一个延迟回调)更新 Label 内容
    auto delay = DelayTime::create(3.0f); // 延迟 3 秒
    auto callFunc = CallFunc::create([label]() {
        label->setString("更新后的中文内容"); // 更新 Label 显示的字符串
    });
    auto sequence = Sequence::create(delay, callFunc, nullptr);
    this->runAction(sequence); 

    return true;
}

解释:首先创建一个初始显示 “初始中文内容” 的 Label ,然后通过 DelayTimeCallFunc 组合实现延迟 3 秒后调用 setString 方法,更新 Label 显示的中文内容为 “更新后的中文内容” 。

五、总结

通过了解中文乱码产生的原因,如字符编码不匹配和字体不支持等,并采取相应的解决措施,如设置正确的编码格式、选用支持中文的字体,以及学习中文读取与显示的拓展应用,如从文件读取中文和动态更新 Label 中文内容,我们就能在 Cocos2d - x 的 Windows 平台开发中,顺利解决 Label 显示中文的问题,为游戏或应用增添丰富的中文信息展示功能。

0 条评论

目前还没有评论...