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!
I’m not a c++ programmer but hopefully faux-code will help…
Class Renderable has the function Render
Class Movable inherits from Renderable and also has properties such as x, y, z and functions like Move
Class Ball inherits from Movable
Now your game state can have a list of Renderable objects and, when the time comes to Render, it can just loop through them.
Other actions, like a tick of the world clock, might loop through looking for objects which are instances of Moveable and tell them to update.
If your Bonus is renderable (I couldn’t tell for sure from your question) then it could subclass Collectable which subclasses Moveable.