0
\$\begingroup\$

I am designing the game so the objects I create (Character, Enemy, Enemycast...) can inherit all from

  • Collider
  • SpineDrawable // Sprite // AnimatedSprite
  • D2D // D3D

Both D2D and D3D inherit from virtual sf::Drawable. D3D also is supossed to apport the functionality of an additional axis. When the object is drawed in screen, the object is scaled and repositioned in (X, Y) with some calculations.

Collider inherits from D3D, because all my colliders are going to have 3 axis, and it creates its own AABB box from D3D interface -to be implemented by the graph type Sprite//SpineDr...-.

I am trying to have two vectors to hold all my graphics, std::vector<D2D*> and std::vector<D3D*>, because the D3D ones will need to be sorted depending on their float z.

The problem arise because D2D///D3D classes inherit virtual sf::Drawable, and I am using my class Sprite inheriting from sf::Sprite, which inherit sf::Drawable as non-virtual function from in Sprite.hpp of SFML.

So I got two questions

  • Must I rewrite my sprite function in lower level, so it can inherit sf::Drawable as virtual?

  • I think my design is poor. Which alternatives are there instead of creating two separated lists of sf::Drawable/s to order the ones which have 3 axis?

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

You might want to look into entity systems. Instead of using inheritance (with all its problems), each entity is composed of pluggable components. See this article for an introduction of the whys and hows.

\$\endgroup\$
1
\$\begingroup\$

I think your idea of separating the types of objects in two lists is actually good. Clearly there's a difference between 2D and 3D things, so don't mix them. It would be nicer though, if you stored them by value in those arrays (instead of pointers), that would gain better CPU cache usage thanks to data locality.

If you put inheritance aside and use composition instead, much like @Thomas suggested, you can store the objects by value. That would also resolve eventual diamond of death issues you might come across.

Without looking at your code, I'd start with something like this (pseudocode):

class Obj3D {
    sf::Drawable myDrawable;
    Vec3 myPostion;

    // methods ...
}

class Obj2D {
    sf::Sprite mySprite;
    Vec2 myPostion;

    // methods ...
}

class Game {
    std::vector<Obj3D> objects3d;
    std::vector<Obj2D> objects2d;
}

If you ever find the need to put everything under a generic Object interface, that englobes both 2D and 3D, then scale-up to that, but try to keep it simple until you really need it.

Lastly, a recommended read, related to this: Component pattern.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .