How to set `sf::Drawable` positions sfml - c++

I'm trying to declare a sf::Drawable * property inside my class body.
the code i already wrote:
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
class View{
protected:
sf::Drawable *view;
};
and inside the class constructor, I want to use the view properties:
class View{
public:
View(){ view->...}
protected:
sf::Drawable *view;
}
but I cannot access any of the sf::Drawable methods.
I get the No member named 'setPosition' in 'sf::Drawable' warning from IDE.
the only code suggestion i get from code completer is:
draw(RenderTarget& target, RenderStates states)

Indeed, sf::Drawable doesn't have a setPosition method. You could instead use sf::Transformable*, which does have setPosition.
If you need to have drawable properties, then...
If all your items are either shapes/sprites/texts, consider walking down the inheritance chain and use sf::Shape, sf::Sprite, or sf::Text.
Make a separate class for each (ShapeView, SpriteView, TextView).
Use dynamic_cast, as suggested by TheMedicineSeller. But this will incur a small runtime cost.

You cannot set the positions of view inside the constructor of View() as sf::Drawable is a purely Abstract class that is meant only for inheritance.
One way to overcome this is by casting between the derived times at runtime but this method is definitely not recommended and can get ugly.
Another is to have the setPosition() function as virtual and consider a separate class say RectangleView which inherits the Base View class which implements the position setting
class View {
protected:
sf::Drawable* view;
virtual void SetPosition() = 0;
};
class RectangleView : public View {
public:
SetPosition();
};
If u ask me, id consider whatever you are trying to do as a bit of overengineering and would advise to not using abstact classes and virtual functions at all for this purpose. Just have specific classes and functions for your sprites and rects.

Related

abstract class A inherited by class C "through" an "intermediary" class B. How to declare the virtual fuctions?

Let's say I have
struct Transformable {
virtual void mirror()=0;
}
class Shape: public Transformable {
Position position;
Color color;
public:
virtual void draw()=0; // 0. <-this, or
virtual void draw(); // I. <-this, or
void draw(); // II. <-this, or maybe
// III. <-this?
}
class Circle {
double radius;
public:
void mirror();
}
(Where Transformable is the abstract class A, Shape is the "intermediary" class B, and Circle is C.)
Which should I use from the cases I-III (noted in //comments above)?
It doesn't make sense for Shape to have a function mirror(), so I would not want to write any code there, choosing option 0 over III.
If I would want to write code, I'd choose I over II.
If I'm right, why? If not, why?
Edit: I need class Shape for a heterogeneous collection, and I made a class Transformable to have transform functions separate from everything. Also I chose to have it go through Shape because this way I don't have to type
AnyShape: public Transformable, public Shape
only
AnyShape: public Shape
Usually, the virtual keyword is only used in the base class. You can omit it in all derived classes and the method will nevertheless be virtual. You can still use it, but it doesn't add much except maybe for readability. Usually, in the derived classes, the keyword override is preferred for overridden virtual methods, because it will check at compile time that you actually override something. So you (usually) have:
class Base{
virtual void method();
};
class Derived : public Base {
void method() override; // still virtual
};
As for the = 0, you add it everywhere that there is no implementation, or where you want to force for a derived non abstract class (i.e. a class you want to instantiate in your code) to implement/override a certain method.
Note that override is only available if you use C++11 and above.
virtual void draw() = 0;
virtual void draw();
are both valid ways declaring the function in Shape.
The choice of whether to use the first one or the second one can be made based on what you expect Shape to do and what you expect its sub-types to do (Circle is the only one you have shown but there will be more I reckon).
If you expect that Shape can take care of some aspects of draw() but the derived classes must have their own implementation, then use the first option. Implement Shape::draw(). Derived classes can make use of Shape::draw() in their implementation.
If you expect that Shape can take care of all aspects of draw() for some classes, then use the second option. In this case, only those derived classes that need to override the function will override it and those that don't need to can leave it out of their implementation.
My suggestion will be to go with the first option. If there are some derived classes that don't need to do anything, they can call Shape::draw() and do nothing more. E.g.
class StrangeShape : public Shape
{
public:
void draw() override { Shape::draw(); }
};

Getting around base class constructor initialization, a bad habit?

I have a base class in an OpenGL project which represents 3DModel in general. Now I want to create a more specialized class that will inherits from 3DModel. My problem is the mandatory base class constructor call in the initialization list. Is there a proper way to delay this call until I've done some computation in the derived constructor?
Here's the important parts of the code:
class 3DModel {
public:
3DModel(std::vector<...> vertices){ ... };
[...]
private:
std::vector<...> vertices;
[...]
};
class Cylinder : public 3DModel {
public:
Cylinder(float top_bottom_ratio, float base_diameter);
[...]
};
//.cpp
Cylinder(float top_bottom_ratio, float base_width)
:3DModel(...) //<---- Mandatory
{
//I would like to calculate the cylinder vertices here
//and then feed them to the 3DModel constructor
}
Right now, I'm thinking of creating a dummy 3DModel() constructor and then call methods inside the derived constructor to modify the attributes of the base class. But this sounds really weird and it'll create a danger zone in the constructor where the object will be invalid for a few moment.
Another solution would be to thrash this class and simply do the computation inside the main program and use 3DModel constructor. But this is a sad solution and ruins the black-box approach.
Do you have any insights?
You can put the calculation into a helper function. Ideally, make it static, so you can't accidentally access unititialized base class values.
class Cylinder : public 3DModel {
public:
Cylinder(float top_bottom_ratio, float base_diameter);
[...]
private:
static calculateVertices(std::vector<...> vertices);
};
//.cpp
Cylinder(float top_bottom_ration, float base_width)
:3DModel(calculateVertices(top_bottom_ratio, base_width))
{
}
std::vector<...> Cylinder::calculateVertices(float top_bottom_ratio, float base_width) {
// calculate and return vertices here
}
You could also opt for composition instead of inheritance, where Cylindar has a 3DModel instead of being a 3DModel. (It would probably need to be something else, e.g. a Renderable that has a render() method.)
This is an example of the classic question of base-subclass vs composite. While the answer does give an example in the form of "base class - subclass", you really have to ask if this can't just be a class 'Cylinder' that contains the '3DModel' class. Unless your Cylinder subclass (and any other subclass) really adds more functionality to the 3DModel class, you really should make Cylinder a composite of the 3DModel class.

Defining a type only by its inheritance from other classes

I am implementing a visual tree in SFML. SFML contains two important drawing classes: sf::Drawable and sf::Transformable. It would be nice if these were bundled up together, but they are not. Many objects inherit from both, i.e.:
class SFML_GRAPHICS_API Text : public Drawable, public Transformable
class SFML_GRAPHICS_API Sprite : public Drawable, public Transformable
class SFML_GRAPHICS_API Shape : public Drawable, public Transformable
For my visual tree, I have a SceneNode class that inherits from Drawable and Transformable, and a draw function will call a private onDraw itself, and then its children. However, many SFML native classes, such as sf::Text, have a draw function that is private. So, I cannot create a class like
class Text: public sf::Text, public SceneNode
and then put it into the visual tree. For these native classes, I don't need them to have draw children anyway, I just want to be able to add them to the visual tree as leaf nodes. The crux of the problem is that each member of the visual tree needs to inherit from sf::Drawable and sf::Tranformable. I need to be able to define a type that inherits from both of these. If I define the dummy class
class LeafNode: public sf::Drawable, public sf::Tranformable { }
which appears to define the type I want. Then, SceneNode will contain std::vector<LeafNode*> m_children. When drawing these children, I will do a dynamic cast on each item to see if it is a SceneNode, and then call a draw function so the SceneNode draws its children.
However the following code does not compile due to type incompatibility:
LeafNode * node = new sf::Text("PLAY", font, 20);
Ideally, I want to define something like
std::vector<sf::Drawable, sf::Transformable*> m_children
Where that made-up syntax means that each element must derive from both sf::Drawable and sf::Transformable. Is this possible?
However, many SFML native classes, such as sf::Text, have a draw function that is private
That's not quite true. Since the sf::Drawable::draw function is protected, so is the draw method of sf::Text. It's one of the complex rules of C++.
So, I cannot create a class like
class Text: public sf::Text, public SceneNode
If you did you would have two sf::Drawable and sf::Transformable base classes in your hierarchy, one from sf::Text and one from SceneNode. That wouldn't be good.
When drawing these children, I will do a dynamic cast on each item to see if it is a SceneNode, and then call a draw function so the SceneNode draws its children.
I would not recommend such design. Using dynamic_cast is usually a sign your software design is not so great. (I don't want to digress too much on this topic, google about that topic.)
But let's answer your fundamental question:
Where that made-up syntax means that each element must derive from both sf::Drawable and sf::Transformable. Is this possible?
No. But you can do simpler things anyway.
Instead of having Text inheriting from both sf::Text and SceneNode, define you class as a wrapper. It can be as simple as:
class Text : public SceneNode {
sf::Text m_text;
public:
sf::Text& get() { return m_text; }
// Override SceneNode drawing method:
virtual void onDraw(RenderTarget& target) const
// Draw m_text:
target.draw(m_text);
}
};
There is two flaws with this quick wrapper, though. a) It doesn't use the transformable part of the SceneNode. b) Since the encapsulation is broken with get() there are two transformable modifiable by the user: the one from SceneNode and the one of sf::Text.
For a), the fix should be straightforward when you have fixed b). To fix b), you have to make the wrapper a little bit more complex: instead of having this ugly get(), write methods to set the properties of the underlying sf::Text that are not linked to sf::Transformable, e.g. setColor.
Without knowing anything about SMFL (which may provide better solutions) I think you can implement this vector. You only need to define your own pointer wrapper, which only accepts pointers to objects which inherits from more than one type:
template <class T1, class T2>
struct special_pointer_wrapper
{
T1* t1;
T2* t2;
template<class T>
special_pointer_wrapper(T* p)
: t1(dynamic_cast<T1*>(p))
, t2(dynamic_cast<T2*>(p))
{
if ((p1==0) || (p2==0))
throw "Error";
}
getT1 T1* () const { return t1; }
getT2 T2* () const { return t2; }
};
This class takes any pointer and ensures its pointed to type is derived from T1 and T2 (even if they seem to be totally unrelated). If its not a derived object it throws. With functions getT1() and getT2() it gives you access to pointers to both base classes.
Please note the construction may be slow due dynamic_cast but extraction of the types is O(1).

Composition pattern

How should one approach composition instead of inheritance? Consider the following class:
class GameObject {...};
class Sprite {
public:
void changeImage(...);
};
class VisibleGameObject: public Sprite, public GameObject {};
class VisibleGameObject : public GameObject {
protected:
Sprite m_sprite;
};
The first VisibleGameObject class uses inheritance. Multiple inheritance. Does not looks good. Second one is what i would like to use, but it won't allow me to access Sprite's API like this:
VisibleGameObject man;
man.changeImage();
How can that be accomplished without inheritance (or code duplication)?
EDIT:
I do know I can just use inheritance or make m_sprite a public member and I can't access the Sprite class because it's private. That's the point, the question is about the best way to change a VisibleGameObject's Sprite, following the rules of data encapsulation.
I think you are still one step behing "composition over inheritance" mindset. The base class should know what to composite. To change image, you should change sprite instance, you shouldn't provide interface of composed instances. For example:
class GameObject {
public:
// you can choose public access or getters and setters, it's your choice
Sprite sprite;
PhysicalBody body;
};
object = GameObject();
object.sprite = graphicalSystem.getSpriteFromImage("image.png");
// or if you prefer setters and getters
object.setSprite(sprite);
More generally GameObject should contain instances (or pointers to instances, depends on your implementation) of base class Component. It makes sense to use inheritance in this case, because this way they can be in one storage like std::map. For example:
class Component {
// ...
};
class Sprite : public Component {
//...
};
class PhysicalBody : public Component {
//...
};
class GameObject {
protected:
std::map<std::string, Component*> components;
//...
public:
Component* getComponent(const std::string& name) const;
void setComponent(const std::string& name, Component* component);
//...
};
For component creation and rendering in main loop use Systems. For example GraphicalSystem knows all instances of Sprite it has created and while rendering it renders only sprites attached to some GameObject instance. Detached component can be garbage collected. Information about position and size might be part of the GameObject or it might be a component "physical".
The best way to understand it is to write your own prototype or to check existing implementations (Artemis, Unity 3D and many others). For more information see Cowboy programming: Evolve Your Hierarchy or try to find Entity/component system.
First of all, the alternative for composition is private inheritance (and not public one) since both model a has-a relationship.
The important question is how can we expose Sprite public members (e.g. changeImage) to VisibleGameObject clients? I present the 4 methods that I know:
(Private) inheritance
I understand that you want to avoid (multiple) inheritance, but for the sake of completeness, I present one suggestion based on private inheritance:
class VisibleGameObject: private Sprite, public GameObject {
...
};
In this case VisibleGameObject privately derives from Sprite. Then users of former cannot access any member of the latter (as if it it were a private member). In particular, Sprite's public and protected members are hidden to VisibleGameObject clients.
Had the inheritance been public, then all Sprite's public and protected members would be exposed by VisibleGameObject to its clients. With private inheritance we have a finer control of which methods should be exposed through using declarations. For instance, this exposes Sprite::changeImage:
class VisibleGameObject1: private Sprite, public GameObject {
public:
using Sprite::changeImage;
...
};
Forwarding methods
We can give to VisibleGameObject public methods that forward the call to m_sprite as show below.
class VisibleGameObject2: public GameObject {
public:
void changeImage() {
m_sprite.changeImage();
}
private:
Sprite m_sprite;
...
};
I believe this is the best design, especially as far as encapsulation is concerned. However, it might require a lot of typing in respect to other alternatives.
Structure dereference operator
Even plain old C provides types that exposes another type's interface as if it was its own: pointers.
Indeed, suppose that p is of type Sprite*. Then by using the structure dereference operator -> we can access members of Sprite (pointed by p) as shown below.
p->changeImage();
C++ allows us to endow classes with customised struct dereference operators (a feature well used by smart pointers). Our example becomes:
class VisibleGameObject3 : public GameObject {
public:
Sprite* operator ->() {
return &m_sprite;
}
private:
Sprite m_sprite;
...
};
and
VisibleGameObject v;
v->changeImage();
Although convenient, this method has many flaws:
As for public inheritance, this approach doesn't give a fine control over which Sprite public members should be exposed.
It works only for one member (that is, you cannot use the same trick to expose two members interfaces).
It messes up with the interface. Indeed, consider for instance that VisualGameObject has a method doSomething(). Then, to call this method on an object v one should do v.doSomething() whereas to call changeImage() one should uses v->changeImage(). This is confusing.
It makes VisibleGameInterface to look like a smart pointer. This is semantically wrong!
C++11 Wrapper Pattern
Finally, there's Sutter's C++11 Wrapper Pattern (watch his presentation, specifically the second slide of page 9):
class VisibleGameObject4 : public GameObject {
private:
Sprite m_sprite;
public:
template <typename F>
auto operator()(F f) -> decltype(f(m_sprite)) {
return f(m_sprite);
}
};
Clients use it this way:
VisibleGameObject4 v4;
v4( [](Sprite& s) { return s.changeImage(); } );
As we can see, compared to the forwarding methods approach this transfer the burden of typing from the class writter to the class clients.
It looks like you are trying to directly access Sprite's function without referencing it first. Try this:
man.m_sprite.changeImage() ;
Note that m_sprite and changeImage() should be public for you to do this. Otherwise use a public accessor function to manipulate private class members.

Multiple inheritance, or something else?

Suppose I have following inheritance tree:
SDLBullet inherits from Bullet inherits from Entity
EnemyBullet inherits form Bullet inherits from Entity
Now I need a new class, SDLEnemyBullet, which needs the draw as implemented in SDLBullet, and the collision as implemented in EnemyBullet. How would I do this? Is this to be solved using multiple inheritance? If not, feel free to edit my question and title. If so, how would I implement such thing?
Some code examples below:
class Entity {
bool collision(Entity) = 0;
void draw() = 0;
}
class Bullet : Entity {
bool collision(Entity) {/*some implementation*/};
void draw() {/*draw me*/};
}
class SDLBullet : Bullet {
void draw() {/*draw me using SDL*/};
}
class EnemyBullet : Bullet {
bool collision(Entity) {/*if Entity is a fellow enemy, don't collide*/};
}
class SDLEnemyBullet : ????? {
/*I need SDLBullet::draw() here*/
/*I need EnemyBullet::collision(Entity) here*/
/*I certainly do not want EnemyBullet::draw nor SDLBullet::collision here*/
}
Any help is much appreciated!
(BTW: This is a school project, and an inheritance tree like this was suggested to us. No one is stopping us from doing it different and better. Thats why I asked the question.)
The textbook solution involves multiple and virtual inheritance.
class SDLBullet : public virtual Bullet {
void draw() {/*draw me using SDL*/};
};
class EnemyBullet : public virtual Bullet {
bool collision(Entity) {/*if Entity is a fellow enemy, don't collide*/};
};
class SDLEnemyBullet : public SDLBullet, public EnemyBullet {
// just one Bullet subobject here
};
Normally, collision stuff is done using multiple dispatch, or in C++, who hasn't this feature, using the visitor pattern.
BUT
why don't you have a hierarchy like this instead ?
class Entity;
class Bullet : public Entity
{
public:
virtual draw();
}
class FriendlyBullet : public Bullet
{
public:
bool collide(EnnemyBullet*);
bool collide(FriendlyBullet*);
}
class EnnemyBullet : public Bullet
{
public:
bool collide(EnnemyBullet*);
bool collide(FriendlyBullet*);
}
This would work too, and wouldn't require multidispatch or multiple inheritance
You need to specify a comma separated list of the super classes:
class SDLEnemyBullet : public SDLBullet, public EnemyBullet {
/*I need SDLBullet::draw() here*/
/*I need EnemyBullet::collision(Entity) here*/
/*I certainly do not want EnemyBullet::draw nor SDLBullet::collision here*/
}
It looks like you're making a game (engine). To avoid the need for complex inheritance structures like this favor composition over inheritance for entities i.e. Have an entity object that contains separate 'component' objects for rendering etc. That way you can mix and match the components however you like without having an explosion of classes with all the different combinations of super classes.
Here's a good article on the subject: http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
Prefer composition over inheritance
You don't need inheritance to combine stuff that's not related like that. Make up basic objects (entities?) for game logic, physics, sound, input, graphics (which may use inheritance) and combine those a GameObject which just has an array of said objects.
Some nifty cross-linking is useful since they will all share a Frame or Transform, but that can be done during creation by iterating over all other objects and using dynamic_cast... (it's useful if you do not need to depend on initialization order).
But there's really no need to build this with inheritance. It doesn't fit your usecase properly. (Although virtual inheritance is useful, it's not a good thing to use inheritance to force different things to become the same, i.e. making everything be a something, instead of being made up of different parts (render, damage, sound, etc...).
Read this and this for more info, or just click the title to google for it. :)