我有一个使用 SFML 库的 C++ 游戏,如果我按转义键,应该绘制一个菜单,因为我有一个 UI 类,当我按转义键时绘制这个类,所以当玩家打开菜单时,对于这个 UI 我有一个 Button 类,它创建一个带有纹理的按钮和一个按下时调用的函数,但我的问题是,即使按钮位置设置为 0,0,Sprite 也在 200,200 左右,但要调用按钮应该执行的函数,我必须在 0,0 左右点击?但是纹理位置除了 0,0 之外没有设置任何其他值? 这是按钮:
Button::Button(float x, float y, float wf, float hf, std::string path, std::function<void()> callback)
: onClick(callback)
{
if (!buttonTexture.loadFromFile(path))
{
std::cerr << "Error loading tilesheet from " << path << std::endl;
}
buttonSprite.setTexture(buttonTexture);
buttonSprite.setPosition(0, 0);
buttonSprite.setScale(wf, hf);
}
void Button::draw(sf::RenderWindow &window)
{
window.draw(buttonSprite);
}
void Button::handleEvent(const sf::Event &event, const sf::RenderWindow &window)
{
if (event.type == sf::Event::MouseButtonPressed)
{
if (event.mouseButton.button == sf::Mouse::Left)
{
sf::Vector2i mousePos = sf::Mouse::getPosition(window);
sf::FloatRect bounds = buttonSprite.getGlobalBounds();
if (bounds.contains(static_cast<float>(mousePos.x), static_cast<float>(mousePos.y)))
{
if (onClick)
{
onClick();
}
}
}
}
}
这是 UI.cpp 中的实现
UI::UI(sf::RenderWindow &window)
{
testButton = new Button(0.0f, 0.0f, 1.0f, 1.0f, "res/Ships/PNGs/ship.png",
[]()
{
std::cout << "Button clicked!" << std::endl;
});
}
按钮也被更新和绘制:
if (UItrue)
{
testButton->handleEvent(event, window);
}
...
if (UItrue)
{
testButton->draw(window);
}
UI 也会在主循环中更新和绘制
我试图打印出buttonSprite的位置,但它说0,0。另外,我用于按钮的图像目前与玩家相同,所以我知道这不是因为这个吗? 如果您需要更多信息或对精灵偏移的原因有任何想法,请告诉我。 另外,如果您想要更多代码,我在 Github 上有它
由于 main.cpp 中的以下两行,精灵出现偏移:
view.setCenter(player.getPosition());
// or
view.setCenter(viewCenter);
您正在将视图更改为以玩家或计算出的
viewCenter
为中心,并且您使用相同的视图来绘制 UI,因此您的 UI 也会移动视图移动的量。
要对此进行调整,您可以为 UI 本身使用单独的视图。有关视图,请参阅[官方教程](https://www.sfml-dev.org/tutorials/2.6/graphics-view.php#using-a-view。
此外,我强烈建议不要在你的
main.cpp
中使用全局变量。最终,由于代码和 SFML 代码之间的初始化/销毁顺序中未定义的行为,您将遇到崩溃。这也使得理解代码流变得更加困难,因为全局状态可以随时更改。