4
\$\begingroup\$

I am quite new to game development, so here is a question (maybe a stupid one):

In my sidescroller i have a bunch of different graphics objects that i need to draw (player, background tiles, creatures, projectiles etc). Most tutorials i've read so far show that each object has its own draw method, which is then called from some other method.

What if I had one method that does all the drawing? Lets say i keep all my objects in an array or queue (or multiple arrays) and then go through each of them, get an image and draw it.

So basically would it be better (and why) to have each object have its own draw method or one method that does all the drawing? Or does it matter at all? I feel like the second option is more comfortable, because then all the stuff to do with drawing would be in one place...

\$\endgroup\$

3 Answers 3

5
\$\begingroup\$

I like to create an interface that defines a "Draw" method. Whenever a class implements that interface, it means that regardless of what else the class can do, it MUST provide the exact "Draw" method as specified in the interface.

Therefore, even if you have a bunch of different objects - a ball, a player, a field - so long as each of them implement the "Drawable" interface, you can iterate through each one of them and call "Draw".

Of course, each class will have to specify what exactly that draw call will do - the interface does not provide this information.

From there, I make a large list of all of my drawable game objects, iterate through it, and call "Draw" on each object.

Quick code example:

Drawable.java:

interface Drawable{
    public void Draw(Graphics g);
}


Ball.java:

class Ball implements Drawable{
    int positionX;
    int positionY;

    public void Draw(Graphics g){
        g.drawOval(positionX, positionY, 5, 5);
    }
}


In your application (main class, likely), have the following:

DrawableStuff = new ArrayList<Drawable>();
DrawableStuff.add(new Ball());
DrawableStuff.add(new Ball());
DrawableStuff.add(new Ball());
DrawableStuff.add(new Duck());
DrawableStuff.add(new Cloud());


Then, in your Component or Canvas' draw function (this depends on your exact implementation, of course):

public void paint(Graphics g){
    for (Drawable d : DrawableStuff){
        d.Draw(g);
    }
}

Now, all of the drawing is called from a single place in your application.

EDIT: One benefit to using this approach is that Draw calls aren't scattered about. Another (more important) benefit is that each class handles the drawing of its instances. So your main application doesn't need to know (or care) how a ball is drawn - all it knows is that (because of the Drawable interface) a ball CAN be drawn (by calling ballObject.Draw(g)). Instead, the Ball class is the only file that holds the code which specifically describes how a ball is drawn. So if you want to change this later on, you only have to modify that one function in the Ball class, nowhere else.

It can also be convenient to maintain several different lists of objects based upon their type, so for example, one list of all the ducks, one of all the turtles, and one of all the clouds, but the reasons for this are likely beyond the scope of this question (one example: to minimize the amount of graphics state that must be changed between 'batches'). This approach is a little more flexible later on down the road.

Wheather you maintain one unified list of Drawables, or multiple lists of objects, you absolutely should define a "Draw" function in the specific class, for the above-mentioned reasons. It might seem like it's adding more code right now while the drawing routines are simple, but once you start having drawing lines that consume pages and pages of code, you'll be very glad that that code is sequestered away in a specific place, not littered about your main game loop with everything else.

This is a very broad topic, but hopefully that gives you an idea of where you can start.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks! I think your edited part of the post answers my questions. \$\endgroup\$
    – delos
    Oct 23, 2012 at 11:26
1
\$\begingroup\$

A typical "Draw" interface that all the graphics object in your game would implement would be something like

public void draw(Graphics gc, int x, int y, double scale) ..

where the Graphics was from the canvas or backing array where the drawing is actually accumulating. x y would mark the center of where the object should go, and scale would be a parameter to scale the object up or down from some arbitrary "normal" size.

Of course, there are many ways to refactor and decorate this with other options, it all depends on what you need for your application.

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

What I would do is keep a public Image reference to every object and draw them in the paint() method of the component.

public class MyObject {

    public Image img;
    public float x, y;

    .....

}

public class MyGame extends JPanel {

    MyObject mo;

    public void paint(Graphics g){
        g.drawImage(mo.img, mo.x, mo.y);
    }

}

It is so easy to make this. And first try using a game engine. You can learn deeper later which takes time.

\$\endgroup\$

You must log in to answer this question.

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