Hey guys, I would like to start a discussion about why all things drawable inherit from transformable. To me it makes sense to use composition to give drawables a transform. E.g. sf::Sprite HAS A transform rather than sf::Sprite IS A transform.
First my use case:
- I want to have a hierarchy of transforms for my sprites or drawables.
- But I don't want that hierarchy to control the draw order
To that end I re-wrote those classes into what I call 'SmartDrawables and SmartTransformables'. They aren't really smart they just allow me to write this:
sf::SmartTransformable rootTransform;
sf::SmartTransformable someTransform;
sf::Sprite rootSprite(rootTransform, texture);
sf::Sprite someSprite(someTransform, texture);
rootTransform.addChild(someTransform);
// In an update somewhere.
rootTransform.rotate(0.1f);
rootTransform.updateTransforms(); // Goes through the heirarchy.
window.draw(someSprite); // Draw in whatever order we want, regardless of parent->child relationship.
window.draw(rootSprite);
So my questions:
- Is this a dumb idea and have I missed something obvious?
- Are there better ways to do this?
- Should SFML follow the 'Prefer composition over inheritance rule' in this situation?
A pic is attached, the blue one represents the child and is being rendered below the parent.
inherit from Transformable rather than contain one, why is that?
What would the API look like if entities contained a transform rather than being transformable? Something like entity.setTransform(sf::Transform)?
I don't see a reason to set a transform after creation although there might be a use case, I prefer to force it as a dependency as it is required. Although I may be wrong! E.g this is my code copy-pasted:
SmartDrawable::SmartDrawable(SmartTransformable& transformable) : sf::Drawable(),
m_smartTransformable(transformable)
{
}
So I guess a simplified question would be: Using that node class as an example, is it better to do my implementation (Making a transformable directly have parent\child relationships and removing the inheritance usage of Transformable) or use that node class and changing it to separate where the combinedTransform is calculated and the drawing occurs?
I'd say it's easier to calculate the transform elsewhere. You can also collect the nodes and reorder them as you want for rendering. There are many possible implementations.
Unless you split the transform calculation and node drawing you can't reorder nodes as that might mess up some specific child->parent relationship. E.g an orb that hovers in front of \ behind a character while also inheriting it's transform wouldn't want to be re-ordered to be the characters parent.