使用sfml绘制精灵时,经常需要水平翻转实现转向。
我尝试使用scale函数直接进行翻转
得到的图像是翻转了,但是没有在原地。而是围绕一根轴线进行的翻转。这根轴不在中心位置,而是在左侧,确切的说,sfml的一切旋转,缩放,位置,都是围绕实体左上点处为原点进行的。
好在sfml有设定原点的函数setOrigin,如果我把图像实体的原点设置在中心处再翻转呢,还是没有按照原地翻转,依旧是翻转后偏移了一些位置,只不过没有直接缩放偏移的严重而已,只偏移了之前的1/2.
m_rectangleShape->setOrigin(sf::Vector2f(m_rectangleShape->getLocalBounds().width/2, 0));
//设置缩放
m_rectangleShape->scale(-1.f, 1.f);原理是,sfml的原点被改变了,位置也会受影响。sfml教程里的话:
By default, entities are positioned relative to their top-left corner. We'll see how to change that with the 'origin' property later.
所以正确的方式是将水平原点设置到图像实体的宽度,这样就可以实现原地水平的翻转
m_rectangleShape->setOrigin(sf::Vector2f(m_rectangleShape->getLocalBounds().width, 0));
//设置缩放
m_rectangleShape->scale(-1.f, 1.f);我可以画图解释,第一张图是设置原点之前图片位置,第二张图是设定原点后图片的位置,第三张图是翻转后图片的位置。所以实现了原地翻转。

在sfml的Drawable类中,在draw函数里可以这样写,通过一个标志位m_isFlip来决定显示的图片是否翻转。
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const{
//翻转动画
if (m_isFlip){
//设置原点
m_rectangleShape->setOrigin(sf::Vector2f(m_rectangleShape->getLocalBounds().width, 0));
//设置缩放
m_rectangleShape->scale(-1.f, 1.f);
}
target.draw(*m_rectangleShape, states);
//恢复翻转
if (m_isFlip){
//恢复缩放
m_rectangleShape->scale(-1.f, 1.f);
//恢复原点
m_rectangleShape->setOrigin(sf::Vector2f(0, 0));
}
}