Hi!
I'm trying to implement some sort of 'just-for-me' game engine and the problem's plot goes the following way:
Suppose I have some abstract interface for a renderable entity, e.g. IRenderable.
And it's declared the following way:
interface IRenderable {
// (...)
// Suppose that Backend is some abstract backend used
// for rendering, and it's implementation is not important
virtual void Render(Backend& backend) = 0;
};
What I'm doing right now is something like declaring different classes like
class Ball : public IRenderable {
virtual void Render(Backend& backend) {
// Rendering implementation, that is specific for
// the Ball object
// (...)
}
};
And then everything looks fine. I can easily do something like std::vector<IRenderable*> items, push some items like new Ball() in this vector and then make a call similiar to foreach (IRenderable* in items) { item->Render(backend); }
Ok, I guess it is the 'polymorphic' way, but what if I want to have different types of objects in my game and an ability to manipulate their state, where every object can be manipulated via it's own interface?
I could do something like
struct GameState {
Ball ball;
Bonus bonus;
// (...)
};
and then easily change objects state via their own methods, like ball.Move(...) or bonus.Activate(...), where Move(...) is specific for only Ball and Activate(...) - for only Bonus instances.
But in this case I lose the opportunity to write foreach IRenderable* simply because I store these balls and bonuses as instances of their derived, not base classes. And in this case the rendering procedure turns into a mess like
ball.Render(backend);
bonus.Render(backend);
// (...)
and it is bad because we actually lose our polymorphism this way (no actual need for making Render function virtual, etc.
The other approach means invoking downcasting via dynamic_cast or something with typeid to determine the type of object you want to manipulate and this looks even worse to me and this also breaks this 'polymorphic' idea.
So, my question is - is there some kind of (probably) alternative approach to what I want to do or can my current pattern be somehow modified so that I would actually store IRenderable* for my game objects (so that I can invoke virtual Render method on each of them) while preserving the ability to easily change the state of these objects?
Maybe I'm doing something absolutely wrong from the beginning, if so, please point it out :)
Thanks in advance!