我有一辆以不同速度移动的汽车精灵。
它位于视图中,视图向左移动,以使汽车始终位于窗口的中心。
视图伴随着汽车的位移,即当汽车加速或制动时它会向左移动。 这样汽车将始终出现在中心。
但是,如果它被另一辆车超越,它将被抛在后面。 因为它不会从窗口消失,我必须放大视图,以便所有的汽车出现。
但为此,我需要知道汽车相对于窗户的位置(与视图无关)。
getGlobalBounds().left
或getPosition().x
显示相同的值,即相对于视图的位置,而不是相对于窗口的位置,如图所示。
如何知道视图中相对于窗口的精灵位置?
答案 0 :(得分:2)
经过几个小时的研究,我终于找到了实现这一目标的简单方法。是的,这太荒谬了。
但首先,我想澄清一些误解。
getGlobalBounds().left
或getPosition().x
显示相同的值, 这是相对于视图的位置,而不是相对于视图的位置 窗口,如图所示。
事实上,这些方法会返回在世界中的位置,而不是在视图中或窗口中。
例如,您可以在500x500
世界中拥有400x400
窗口,其中包含10000x10000
视图。您可以在视图或窗口之外的世界中放置内容。当渲染世界时,视图的变换(平移,旋转,缩放......)将应用于世界,并且最终会在窗口中显示内容。
要知道世界中的坐标在窗口(或任何其他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;
}