Sign in to follow this  
chbrules

Program Design Theory - Managing How To Draw To Screen

Recommended Posts

chbrules    170
So I'm writing a little 2D game for fun in C++ with the SFML API. You don't need to know about it anymore than this fact: to draw a sprite to the screen you have to pass it to the draw member method of the base window class you create. I just called it "App." So basically you go "App.draw(sprite);".

My problem comes to the design of the whole shabang. What I've ended up doing is simply passing a reference to "App" in the constructor of all the drawable objects. Every drawable/animated object has a draw member method (inherited from base class), so I just let it handle all the drawing itself in one convenient function I iterate through in a manager class using a pointer array of the base class.

Maybe I'm just crazy, but I feel this is rather sloppy. Does anyone have any input on this? Am I being an idiot doing it this way? Thanks! [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img] Edited by chbrules

Share this post


Link to post
Share on other sites
SuperVGA    1132
That's a classic!

Pretend that we're writing a nice, modular piece of software. The lead announces that by the next baseline,
the near-graphics core of the code follows open for extensions / closed for modifications -principle.
(http://en.wikipedia.org/wiki/Open/closed_principle)
Now the App(the near-graphics core) cannot be modified although you want support for new sprites. Ouch!
- What went wrong?

See, if the "canvas" needs to know how to draw everything, the drawing code will easily bloat that code module / class.
If the individual drawable classes know how to draw themselves, given a bit of render context information, it makes the process extensible.
You can do this by implementing a "drawable/renderable" interface, a delegate or inheriting from a renderable base class
(depending on your language)

Hope this helps - Good luck with your project! :) Edited by SuperVGA

Share this post


Link to post
Share on other sites
NightCreature83    5002
You can also use render lists, in this way a game object doesn't need to know how to render to screen, it just needs to know what of its data needs to be rendered. This is then collated in a list and that list is then used by the renderer to issue render commands.

The benefit of this is that you can do some sorting on the render list before rendering without having to sort the scenegraph or other hierarchy in which you store your renderable data.

Share this post


Link to post
Share on other sites
chbrules    170
[quote name='NightCreature83' timestamp='1351599141' post='4995370']
You can also use render lists, in this way a game object doesn't need to know how to render to screen, it just needs to know what of its data needs to be rendered. This is then collated in a list and that list is then used by the renderer to issue render commands.

The benefit of this is that you can do some sorting on the render list before rendering without having to sort the scenegraph or other hierarchy in which you store your renderable data.
[/quote]

Great idea! Is there an example of this setup you could point me to? I learn well by example :]

Share this post


Link to post
Share on other sites
Practically speaking, I think what the OP is doing seems totally fine for a small game.

If you want to do a more complicated design for the sake of learning, I'd probably look into separating the game object logic from the presentation, so you could e.g. swap your sprite rendering into a dummy ASCII rendering without having to touch the game objects.

I'm personally interested in implementing a component-based game model, but it's not a magic bullet either. For instance, if you have a game logic object with complex state, it seems like an inherently messy problem how to convey another component sufficient information to render it in the presence of animations, etc.

Share this post


Link to post
Share on other sites
BeerNutts    4400
You can also have your drawble classes inherit from sf::Sprite class. So, you're actual class is a sprite, and you can pass it to the App.Draw, like this:
[code]
class Drawable : public sf::Sprite
{
Drawable::Drawable(sf::Image sfImage, ...) :
sf::Sprite(sfImage)
{
//.. other constructor stuff
}
};

// list that holds eveyrthing thta can be drawn
std::vector<Drawable> DrawableList;

// called from in main loop
void DrawObjects(sf::RenderWindow &App)
{
for (int i = 0; i < DrawableList.size(); ++i) {
App.Draw(DrawableList[i]);
}
}
[/code]

You get the general idea. Of course, if your drawable handle animation, then it can't be a single sprite, but this is just another option you could choose.

Good luck! Edited by BeerNutts

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this