C++ SFML学习笔记之Text显示汉字
最近刚开始学习SFML,路上遇到了许多坑,但是我想,每解决一个问题就记录下来,一方面方便自己记忆,一方面避免大家跟我踩相同的坑。
显示中文的问题
我们写游戏,汉字问题是必不可少的,这里SFML提供了非常友好的Text类,显示英文没问题,只要
// textTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(400, 400), "SFML works!");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
sf::Font font;
font.loadFromFile("arial.ttf");//-----第一个坑--------
sf::Text text;
text.setFont(font);
text.setString("hello world!");//-----第二个坑--------
text.setCharacterSize(24);
text.setFillColor(sf::Color::Red);
text.setStyle(sf::Text::Bold | sf::Text::Underlined);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(shape);
window.draw(text);//记得画出来
window.display();
}
return 0;
}
第一个坑,没有字体文件的话,会报错,如果不写font的话,他也不会去找默认的字体(直接啥也不显示),我的解决办法是去控制面板字体库里选一个复制到主文件.cpp旁边去,这样显示就没问题了
第二个坑,中文乱码,,如果我们改成中文
text.setString("这里会显示乱码")
赶紧去百度,然后查官方文档,
大概意思是说,可以使用宽文本字符串(Wide String)
text.setString(L"这样就不会显示乱码")
再试试
反正是没有报错,但是好像是文本缺失,所以。。。换个字体?去网上随便找个字体
加载成功了,可能有点丑,去系统库里拿个中文字体也可以
那么新的问题来了,我把中文字段写在了一个vector里,
vector<string> contents = { "你好","这是一个demo1","这是一个demo2","这是一个demo3" }
,那么循环调用的时候
text.setString(contents2[i % 4])
,如果我写成
vector<string> contents2 = { L"你好",L"这是一个demo",L"这是一个demo",L"这是一个demo" }
,这样会报错,如果我写成
text.setString(L contents2[i % 4])
更会报错,怎么办呢?
我之前在优快云和知乎都发了提问,但是没人回,忽然,好像灵光一现的,是不是我vector的类型有问题,我之前是学python的,C++懂的不是很多,以为c++的L"string"和python的f"string"是差不多的东西,但其实不是,c++的L"string"的类型不再是string,而是wstring
std::vector<std::wstring> contents = { L"你好",L"这是一个demo1",L"这是一个demo2",L"这是一个demo3" };
报错消失了,以下贴出完整代码
// textTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(400, 400), "SFML works!");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
sf::Font font;
font.loadFromFile("也字工厂山海明朝.ttf");
sf::Text text;
text.setFont(font);
text.setCharacterSize(24);
text.setFillColor(sf::Color::Red);
text.setStyle(sf::Text::Bold | sf::Text::Underlined);
std::vector<std::wstring> contents = { L"你好",L"这是一个demo1",L"这是一个demo2",L"这是一个demo3" };
int i = 0;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
i++;
text.setString(contents[i % 4]);
window.clear();
window.draw(shape);
window.draw(text);
window.display();
}
return 0;
}
变得太快是是吗,我们还可以加个Clock
float timer1 = 0, timer2 = 0, delay = 1; //时间工具和延时
sf::Clock clock;
时间累积
timer2 = clock.getElapsedTime().asSeconds();//表示自上次调用 restart() 或计时器创建以来经过的时间
clock.restart();
timer1 += timer2;
if (timer1 > delay) {
i++;
timer1 = 0;
}
完整代码
// textTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(400, 400), "SFML works!");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
sf::Font font;
font.loadFromFile("也字工厂山海明朝.ttf");
sf::Text text;
text.setFont(font);
text.setCharacterSize(24);
text.setFillColor(sf::Color::Red);
text.setStyle(sf::Text::Bold | sf::Text::Underlined);
std::vector<std::wstring> contents = { L"你好",L"这是一个demo1",L"这是一个demo2",L"这是一个demo3" };
int i = 0;
float timer1 = 0, timer2 = 0, delay = 1; //时间工具和延时
sf::Clock clock;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
timer2 = clock.getElapsedTime().asSeconds();//表示自上次调用 restart() 或计时器创建以来经过的时间
clock.restart();
timer1 += timer2;
if (timer1 > delay) {
i++;
timer1 = 0;
}
text.setString(contents[i % 4]+std::to_wstring(timer1));
window.clear();
window.draw(shape);
window.draw(text);
window.display();
}
return 0;
}