在 SFML 中将精灵保存为数组
Saving Sprites as Arrays in SFML
好吧,所以我正在尝试创建一个程序,当用户按下 A 时绘制 A 的图片。我还没有接近那一步,但只是让您了解最终目标是什么。无论如何,我尝试创建一个名为 DrawKey(string key)
的函数,我已经正确设置了它,问题是它没有绘制精灵。我不知道我哪里错了,请帮忙。
static void DrawKey(string key)
{
sf::RenderWindow Key(sf::VideoMode(800, 600), "A");
sf::Style::None;
while (Key.isOpen())
{
//Sprites
map<string, sf::Sprite> Sprite;
map<string, sf::Texture> Tex;
sf::Texture ATex;
ATex.loadFromFile("Assets/Images/A.jpg");
sf::Texture DTex;
DTex.loadFromFile("Assets/Images/D.jpg");
sf::Texture ETex;
ETex.loadFromFile("Assets/Images/E.jpg");
sf::Texture QTex;
sf::Texture STex;
QTex.loadFromFile("Assets/Images/Q.jpg");
STex.loadFromFile("Assets/Images/S.jpg");
sf::Texture WTex;
WTex.loadFromFile("Assets/Images/W.jpg");
sf::Texture XTex;
XTex.loadFromFile("Assets/Images/X.jpg");
sf::Texture ZTex;
ZTex.loadFromFile("Assets/Images/Z.jpg");
sf::Texture EscTex;
EscTex.loadFromFile("Assets/Images/esc.jpg");
Tex["A", "D", "E", "Q", "S", "W", "X", "Z", "Esc"] = ATex, DTex, ETex, QTex, STex, WTex, XTex, ZTex, EscTex;
sf::Sprite ASprite;
ASprite.setTexture(ATex);
sf::Sprite DSprite;
ASprite.setTexture(Tex["D"]);
sf::Sprite ESprite;
ASprite.setTexture(Tex["E"]);
sf::Sprite QSprite;
ASprite.setTexture(Tex["Q"]);
sf::Sprite SSprite;
ASprite.setTexture(Tex["S"]);
sf::Sprite WSprite;
ASprite.setTexture(Tex["W"]);
sf::Sprite XSprite;
ASprite.setTexture(Tex["X"]);
sf::Sprite ZSprite;
ASprite.setTexture(Tex["Z"]);
sf::Sprite EscSprite;
ASprite.setTexture(Tex["Esc"]);
Sprite["A", "D", "E", "Q", "S", "W", "X", "Z", "Esc"] = ASprite, DSprite, ESprite, QSprite, SSprite, WSprite, XSprite, ZSprite, EscSprite;
// Process events
sf::Event event;
while (Key.pollEvent(event))
{
// Close window: exit
if (event.type == sf::Event::Closed)
Key.close();
}
// Clear screen
Key.clear(sf::Color::Transparent);
Key.draw(Sprite[key]);
Key.display();
}
是的,我知道我可以让它写一封信,我想要它作为图像。
感谢您的帮助,我对这一切都是陌生的。
C++ 中的逗号运算符是很多初学者经常犯的错误。它计算其中的所有表达式(并考虑它们的副作用)但只有 return 是最右边的值。
Sprite["A", "D", "E", "Q", "S", "W", "X", "Z", "Esc"] = ASprite, DSprite, ESprite, QSprite, SSprite, WSprite, XSprite, ZSprite, EscSprite;
等同于(因为各种逗号表达式的操作数 none 有副作用):
Sprite["Esc"] = EscSprite;
我很好奇点击 Esc
是否会按预期绘制 EscSprite
。
你问,"Well why doesn't the program crash when I try to access the "地图上的“钥匙”?
Key.draw(Sprite[key]);
答案是 std::map
上的 []
运算符将检索该键的值,除非该键不存在,在这种情况下它将默认构造值和 return 那个.
根据我的阅读,您的代码存在一些问题:
它不起作用的几个原因
逗号错误
您似乎使用逗号来表达您的意图,就像您在此处使用其他语言一样:
Tex["A", "D", "E", "Q", "S", "W", "X", "Z", "Esc"] = ATex, DTex, ETex, QTex, STex, WTex, XTex, ZTex, EscTex;
在 C++ 中不能这样使用逗号。此处使用内置的逗号运算符。如此处指定:
https://en.cppreference.com/w/cpp/language/operator_other
In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded (although if it has class type, it won't be destroyed until the end of the containing full expression), and its side effects are completed before evaluation of the expression E2 begins (note that a user-defined operator, cannot guarantee sequencing) (until C++17).
这里每个表达式后面跟一个逗号什么都不做,直到最后一个参数才会被使用,所以你的表达式只有Tex["Esc"] = EscTex;
.
后面的行也是如此
Sprite["A", "D", "E", "Q", "S", "W", "X", "Z", "Esc"] = ASprite, DSprite, ESprite, QSprite, SSprite, WSprite, XSprite, ZSprite, EscSprite;
稍后,当您尝试使用 Tex["A"] 时,它会创建一个新的空纹理,因为您从未指定任何纹理。
复制粘贴错误
每个 setTexture
函数都在 ASprite
上调用,我认为这不是你的意图。
各种建议
初始化一次
你永远不应该在你的渲染(或任何)循环中从同一个文件加载,因为这是一个非常昂贵的操作。即使创建精灵也只需要一次,避免了每帧的创建成本。
一致规范
你有一些以大写字母开头的变量,有些不是,请尽量保持一致。在 C++ Core Guidelines
中指定
其他
sf::Style::None; //<This line doesn't do anything
编辑
要以 C++ 方式解决逗号错误,请使用映射的初始化列表:
map<string, sf::Texture> Tex;
Tex = {
{ "A", ATex },
{ "B", BTex },
{ "C", CTex },
// ...
};
好吧,所以我正在尝试创建一个程序,当用户按下 A 时绘制 A 的图片。我还没有接近那一步,但只是让您了解最终目标是什么。无论如何,我尝试创建一个名为 DrawKey(string key)
的函数,我已经正确设置了它,问题是它没有绘制精灵。我不知道我哪里错了,请帮忙。
static void DrawKey(string key)
{
sf::RenderWindow Key(sf::VideoMode(800, 600), "A");
sf::Style::None;
while (Key.isOpen())
{
//Sprites
map<string, sf::Sprite> Sprite;
map<string, sf::Texture> Tex;
sf::Texture ATex;
ATex.loadFromFile("Assets/Images/A.jpg");
sf::Texture DTex;
DTex.loadFromFile("Assets/Images/D.jpg");
sf::Texture ETex;
ETex.loadFromFile("Assets/Images/E.jpg");
sf::Texture QTex;
sf::Texture STex;
QTex.loadFromFile("Assets/Images/Q.jpg");
STex.loadFromFile("Assets/Images/S.jpg");
sf::Texture WTex;
WTex.loadFromFile("Assets/Images/W.jpg");
sf::Texture XTex;
XTex.loadFromFile("Assets/Images/X.jpg");
sf::Texture ZTex;
ZTex.loadFromFile("Assets/Images/Z.jpg");
sf::Texture EscTex;
EscTex.loadFromFile("Assets/Images/esc.jpg");
Tex["A", "D", "E", "Q", "S", "W", "X", "Z", "Esc"] = ATex, DTex, ETex, QTex, STex, WTex, XTex, ZTex, EscTex;
sf::Sprite ASprite;
ASprite.setTexture(ATex);
sf::Sprite DSprite;
ASprite.setTexture(Tex["D"]);
sf::Sprite ESprite;
ASprite.setTexture(Tex["E"]);
sf::Sprite QSprite;
ASprite.setTexture(Tex["Q"]);
sf::Sprite SSprite;
ASprite.setTexture(Tex["S"]);
sf::Sprite WSprite;
ASprite.setTexture(Tex["W"]);
sf::Sprite XSprite;
ASprite.setTexture(Tex["X"]);
sf::Sprite ZSprite;
ASprite.setTexture(Tex["Z"]);
sf::Sprite EscSprite;
ASprite.setTexture(Tex["Esc"]);
Sprite["A", "D", "E", "Q", "S", "W", "X", "Z", "Esc"] = ASprite, DSprite, ESprite, QSprite, SSprite, WSprite, XSprite, ZSprite, EscSprite;
// Process events
sf::Event event;
while (Key.pollEvent(event))
{
// Close window: exit
if (event.type == sf::Event::Closed)
Key.close();
}
// Clear screen
Key.clear(sf::Color::Transparent);
Key.draw(Sprite[key]);
Key.display();
}
是的,我知道我可以让它写一封信,我想要它作为图像。 感谢您的帮助,我对这一切都是陌生的。
C++ 中的逗号运算符是很多初学者经常犯的错误。它计算其中的所有表达式(并考虑它们的副作用)但只有 return 是最右边的值。
Sprite["A", "D", "E", "Q", "S", "W", "X", "Z", "Esc"] = ASprite, DSprite, ESprite, QSprite, SSprite, WSprite, XSprite, ZSprite, EscSprite;
等同于(因为各种逗号表达式的操作数 none 有副作用):
Sprite["Esc"] = EscSprite;
我很好奇点击 Esc
是否会按预期绘制 EscSprite
。
你问,"Well why doesn't the program crash when I try to access the "地图上的“钥匙”?
Key.draw(Sprite[key]);
答案是 std::map
上的 []
运算符将检索该键的值,除非该键不存在,在这种情况下它将默认构造值和 return 那个.
根据我的阅读,您的代码存在一些问题:
它不起作用的几个原因
逗号错误
您似乎使用逗号来表达您的意图,就像您在此处使用其他语言一样:
Tex["A", "D", "E", "Q", "S", "W", "X", "Z", "Esc"] = ATex, DTex, ETex, QTex, STex, WTex, XTex, ZTex, EscTex;
在 C++ 中不能这样使用逗号。此处使用内置的逗号运算符。如此处指定: https://en.cppreference.com/w/cpp/language/operator_other
In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded (although if it has class type, it won't be destroyed until the end of the containing full expression), and its side effects are completed before evaluation of the expression E2 begins (note that a user-defined operator, cannot guarantee sequencing) (until C++17).
这里每个表达式后面跟一个逗号什么都不做,直到最后一个参数才会被使用,所以你的表达式只有Tex["Esc"] = EscTex;
.
后面的行也是如此
Sprite["A", "D", "E", "Q", "S", "W", "X", "Z", "Esc"] = ASprite, DSprite, ESprite, QSprite, SSprite, WSprite, XSprite, ZSprite, EscSprite;
稍后,当您尝试使用 Tex["A"] 时,它会创建一个新的空纹理,因为您从未指定任何纹理。
复制粘贴错误
每个 setTexture
函数都在 ASprite
上调用,我认为这不是你的意图。
各种建议
初始化一次
你永远不应该在你的渲染(或任何)循环中从同一个文件加载,因为这是一个非常昂贵的操作。即使创建精灵也只需要一次,避免了每帧的创建成本。
一致规范
你有一些以大写字母开头的变量,有些不是,请尽量保持一致。在 C++ Core Guidelines
中指定其他
sf::Style::None; //<This line doesn't do anything
编辑
要以 C++ 方式解决逗号错误,请使用映射的初始化列表:
map<string, sf::Texture> Tex;
Tex = {
{ "A", ATex },
{ "B", BTex },
{ "C", CTex },
// ...
};