我正在使用C ++中的SFML进行小行星的基本实现,以使用组件 - 实体 - 系统框架进行练习。
从概念上讲,像玩家船,浮动小行星等物体共享共同的“组件”是有意义的,例如图形组件,速度组件和方向/位置组件。这使问题分离,并具有一系列的好处。
然而,在SFML中,精灵被渲染到一个只有他们知道的固定位置!这立即意味着我的图形组件和方向/位置组件必须组合或必须彼此了解,这违背了组件 - 实体 - 系统方法的整体思路。另一方面,在SDL中,您可以轻松地将纹理渲染到从任何位置构建的单独矩形。
我的问题是:必须有一些具体的推理背后为什么SFML中的精灵会依赖自己的位置信息 - 这是什么原因?也许如果我更好地理解这一点,我可以形成一个很好的解决方案。
答案 0 :(得分:3)
sf::Sprite
类基本上是一种以易于使用的方式绘制精灵的快速方法。
对于更高级的用例,它们不一定是最好的,主要是因为它们相当慢(因为它们没有被攻击)。
sf::Sprite
主要面向想要在屏幕上轻松获取精灵的人,而不必过多担心实现细节(与其他sf::Drawable
派生类一样)。
你应该做的是实现你自己的可绘制或可视组件,它存储颜色,纹理和UV坐标。 Mabye是这样的:
struct DrawableComponent {
sf::Color color;
sf::Texture *texture;
sf::IntRect uv;
}
当然可能有其他方法有更多选项或各种组件(例如矢量图形与纹理四边形)。
然后,绘制时,使用可以批处理的相同纹理迭代所有实体,并将它们的顶点放入std::vector
或sf::VertexArray
,并使用它们进行快速批量渲染。
答案 1 :(得分:2)
SFML遵循面向对象的设计。 sf::Sprite
模拟一个可见的东西,它有一个纹理和一个变换。因此,正如在OOD中一样,它具有这两个属性。
这与ECS设计直接相悖,ECS设计努力通过不让任何实体持有任何内容来扭转这种局面。您无法真正将sf::Sprite
类集成到您的设计中 - 它从根本上说是不兼容的。当您收集了所需的所有数据时,您可以做的最好的事情是在显示时创建一个临时sf::Sprite
。
对于SDL ......好吧,与SFML不同,它只是一个低级别的图形API(以及其他)。它不会尝试模拟任何东西:采取纹理,将其拍在帧缓冲区上,就是这样。两种截然不同的工具,用于完全不同的目标。