如何知道视图内精灵相对于 window 的位置?
How to know a sprite position inside a view, relative to window?
我有这个以不同速度移动的汽车精灵。
它在一个视图内,视图向左移动以使汽车始终位于 window 的中心。
视图伴随着汽车的位移,即随着汽车加速或制动而向左移动。
这样小车就会一直出现在中间
但是,如果它被另一辆车超越,它就会落在后面。
为了不让它从 window 中消失,我必须放大视图以便所有汽车都出现。
但是为此,我需要知道汽车相对于 window 的位置(而不是相对于视图)。
getGlobalBounds().left
或 getPosition().x
显示相同的值,即相对于视图的位置,而不是相对于 window 的位置,如图所示。
如何知道视图中精灵相对于 window 的位置?
经过几个小时的研究,我终于找到了实现这一目标的简单方法。是的,这太简单了。
但首先,我想澄清一些误解。
getGlobalBounds().left
or getPosition().x
show the same value,
which is the position relative to the view, not relative to the
window, as shown in the image.
事实上,那些方法return在世界中的位置,不在视图中也不在window中。
例如,您可以在 10000x10000
世界中拥有 500x500
window 和 400x400
视图。您可以将事物放置在世界中、视图或 window 之外。渲染世界后,视图的变换(平移、旋转、缩放等)将应用到世界,事物最终显示在 window.
中
要知道世界坐标在 window(或任何其他 RenderTarget)中的表示位置,反之亦然,SFML 实际上有几个函数:
RenderTarget.mapCoordsToPixel(Vector2f point)
给定一个点在世界给你相应的点在RenderTarget.
RenderTarget.mapPixelToCoords(Vector2f point)
在 RenderTarget 中给定一个点 给你在世界 中的对应点 。 (这对于将鼠标点击映射到您的世界中的相应点很有用)
结果
代码
int main()
{
RenderWindow window({ 500, 500 }, "SFML Views", Style::Close);
sf::View camera(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
sf::Vector2f orig(window.getSize().x / 2, window.getSize().y / 2);
camera.setCenter(orig);
sf::Font f;
f.loadFromFile("C:/Windows/Fonts/Arial.ttf");
sf::Text t;
t.setFont(f);
sf::RectangleShape r;
r.setPosition(10, 10);
r.setSize(sf::Vector2f(20, 20));
r.setOutlineColor(sf::Color::Blue);
r.setFillColor(sf::Color::Blue);
t.setPosition(10, 40);
while (window.isOpen())
{
for (Event event; window.pollEvent(event);)
if (event.type == Event::Closed)
window.close();
else if (event.type == Event::KeyPressed){
camera.move(-3, 0);
camera.rotate(5.0);
camera.zoom(1.1);
}
auto realPos = window.mapCoordsToPixel(r.getPosition());
std::string str = "Pos: (" + std::to_string(realPos.x) +","+ std::to_string(realPos.y) + ")";
t.setString(str);
window.clear();
window.setView(camera);
window.draw(r);
window.draw(t);
window.display();
}
return EXIT_SUCCESS;
}
我有这个以不同速度移动的汽车精灵。
它在一个视图内,视图向左移动以使汽车始终位于 window 的中心。
视图伴随着汽车的位移,即随着汽车加速或制动而向左移动。 这样小车就会一直出现在中间
但是,如果它被另一辆车超越,它就会落在后面。 为了不让它从 window 中消失,我必须放大视图以便所有汽车都出现。
但是为此,我需要知道汽车相对于 window 的位置(而不是相对于视图)。
getGlobalBounds().left
或 getPosition().x
显示相同的值,即相对于视图的位置,而不是相对于 window 的位置,如图所示。
如何知道视图中精灵相对于 window 的位置?
经过几个小时的研究,我终于找到了实现这一目标的简单方法。是的,这太简单了。
但首先,我想澄清一些误解。
getGlobalBounds().left
orgetPosition().x
show the same value, which is the position relative to the view, not relative to the window, as shown in the image.
事实上,那些方法return在世界中的位置,不在视图中也不在window中。
例如,您可以在 10000x10000
世界中拥有 500x500
window 和 400x400
视图。您可以将事物放置在世界中、视图或 window 之外。渲染世界后,视图的变换(平移、旋转、缩放等)将应用到世界,事物最终显示在 window.
要知道世界坐标在 window(或任何其他 RenderTarget)中的表示位置,反之亦然,SFML 实际上有几个函数:
RenderTarget.mapCoordsToPixel(Vector2f point)
给定一个点在世界给你相应的点在RenderTarget.
RenderTarget.mapPixelToCoords(Vector2f point)
在 RenderTarget 中给定一个点 给你在世界 中的对应点 。 (这对于将鼠标点击映射到您的世界中的相应点很有用)
结果
代码
int main()
{
RenderWindow window({ 500, 500 }, "SFML Views", Style::Close);
sf::View camera(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
sf::Vector2f orig(window.getSize().x / 2, window.getSize().y / 2);
camera.setCenter(orig);
sf::Font f;
f.loadFromFile("C:/Windows/Fonts/Arial.ttf");
sf::Text t;
t.setFont(f);
sf::RectangleShape r;
r.setPosition(10, 10);
r.setSize(sf::Vector2f(20, 20));
r.setOutlineColor(sf::Color::Blue);
r.setFillColor(sf::Color::Blue);
t.setPosition(10, 40);
while (window.isOpen())
{
for (Event event; window.pollEvent(event);)
if (event.type == Event::Closed)
window.close();
else if (event.type == Event::KeyPressed){
camera.move(-3, 0);
camera.rotate(5.0);
camera.zoom(1.1);
}
auto realPos = window.mapCoordsToPixel(r.getPosition());
std::string str = "Pos: (" + std::to_string(realPos.x) +","+ std::to_string(realPos.y) + ")";
t.setString(str);
window.clear();
window.setView(camera);
window.draw(r);
window.draw(t);
window.display();
}
return EXIT_SUCCESS;
}