• Advertisement
Sign in to follow this  

Help with good use of virtual functions in game structure

This topic is 2114 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all,

My question is on how you use virtual functions within your game. I understand the general concept, for example, you'd have a 'weapon' base class that has a virtual function 'attack', this can then be overridden in derived classes such as a sword or axe where you would write the concrete function for 'attack'. My confusion comes from how best to use it for a 'update' function that the game would call. Say you had a base 'entity' class, which had a virtual 'update' function. Derived from this you could have 'renderEntity' with both an update and a 'draw' function and finally a 'player' class which inherits renderEntity and also has it's own definition of the 'update' virtual function. Should each override of the 'update' virtual function only contain update code relevant to that class, and then call the 'update' function from the class it inherits from? Forming a kind of call chain, ie:

class entity
{
entity();
~entity();
virtual void update();
};

class renderEntity : public entity
{
renderEntity();
~renderEntity();
void draw();
void update(){ draw(); };
};

class player : public renderEntity
{
player();
~player();
void update(){/*player specific update code*/ renderEntity::update(); }; //Does player update and then calls the parent update();
};

//Then in your main loop in the update section you'd have something like:
void update()
{
for(int i = 0; i < entities.size(); i++)
{
entities.update();
}
}

(sorry for the crude example, but hopefully you'll get the idea.)

Is this similar to how you structure your game classes enabling them all with their own update() definition that calls the parent update and so on? I understand there's probably a thousand ways to do this, but I feel my way could be improved.

Thanks for reading and thanks in advance!

Share this post


Link to post
Share on other sites
Advertisement
This is certainly an option; but it becomes unwieldy very quickly in non-trivial projects.

Generally speaking, you should prefer composition over inheritance. In other words, a Player should have a Renderable member which represents its graphical representation, and possibly also members like Inventory and Health and whatever else comprises a Player. Then you can maintain a container of all Renderables in the game that only your graphics system needs to care about, and use that container to directly invoke Render() on every Renderable you have. Done correctly, this can eliminate virtual dispatch entirely, and even in the most contorted situations it will make most of your virtual calls go away.

This kind of approach is much more maintainable as the complexity and richness of your game logic increases, and has concrete benefits in organization and readability of your code in general.

Share this post


Link to post
Share on other sites
Thanks for the reply, the component system certainly sounds better. It seems that the code might also be more reusable than that of an inheritance based system. Most of the games I've worked on structure wise has always been a version of my example and it annoyed me the fact that my base structure was different nearly every time. So as for the component, game objects are created by adding (or removing) functional components to that object? Would each component then also be attached to a manager (as you suggested) for that component, ie you might have a RenderComponentManager, which would update/render? So the main loop would look something like this:


while(running)
{
InputComponentManager.updateAll();
RenderComponentManager.updateAll();
}//So rather than updating a specific object, you're just updating the components independently?


So each render component would draw it's self to the screen:


class Renderable : public component
{
public:
Sprite sprite;
Renderable();
~Renderable();
void Render(){ Engine *tmp = Engine::getInstance(); tmp->getWindow()->draw(sprite); };
void SetSprite(std::string fileName){/*sprite loaded from file here*/};
}


Is this the kind of way it would work? Thanks again for the help.

Share this post


Link to post
Share on other sites
Sure, although I'd make the minor tweak of never using singletons and instead passing your Engine directly to Render(). Other than that, sounds like you've got the concept down!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement