Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am very new to game development, but not to programming.

I am (again) playing around with a Pong type game using JavaScript's canvas element.

I have created a Paddle object which has the following properties...

  • width
  • height
  • x
  • y
  • colour

I also have a Pong object which has properties such as...

  • width
  • height
  • backgroundColour
  • draw().

The draw() method currently is resetting the canvas and that is where a question came up.

Should the Paddle object have a draw() method responsible for its drawing, or should the draw() of the Pong object be responsible for drawing its actors (I assume that is the correct term, please correct me if I'm incorrect).

I figured that it would be advantagous for the Paddle to draw itself, as I instantiate two objects, Player and Enemy. If it were not in the Pong's draw(), I'd need to write similar code twice.

What is the best practice here?

Thanks.

share|improve this question
    
Similar question: gamedev.stackexchange.com/questions/13492/… –  Byte56 Jun 25 '11 at 6:40

5 Answers 5

up vote 28 down vote accepted

Having actors draw themselves is not a good design, for two main reasons:

1) it violates the single responsibility principle, as those actors presumably had another job to do before you shoved render code into them.

2) it makes extension difficult; if every actor type implements its own drawing, and you need to change the way you draw in general, you may have to modify a lot of code. Avoiding overuse of inheritance can alleviate this to some extent, but not completely.

It's better for your renderer to be handling the drawing. After all, that's what it means to be a renderer. The renderer's draw method should take a "render description" object, which contains everything you need to render a thing. References to (probably shared) geometry data, instance-specific transformations or material properties such as color, et cetera. It then draws that, and doesn't care what that render description is supposed to "be."

Your actors can then hold on to a render description they create themselves. Since actors are typically logic processing types, they can push state changes to the render description as needed -- for example, when an actor takes damage it could set the color of its render description to red to indicate this.

Then you can simply iterate every visible actor, enqeue their render descriptions into the renderer, and let it do its thing (basically; you could generalize this even further).

share|improve this answer
    
+1 thanks Josh, this makes the most sense to me. –  alex Jun 25 '11 at 2:35
    
+1: More developers need to learn how to avoid the entity fat-interface problem. –  Nicol Bolas Jun 25 '11 at 4:00
10  
+1 for "renderer drawing code," but -1 for single responsibility principle, which has done programmers more harm than good. It's got the right idea (separation of concerns), but the way it's stated ("every class should have only one responsibility, and/or only one reason to change") is simply wrong. –  BlueRaja - Danny Pflughoeft Jun 25 '11 at 5:46
1  
-1 for 1), as BlueRaja pointed out, this principle is idealist, but not practical. -1 for 2) because it doesn't make extension significantly more difficult. If you have to change your entire rendering engine, you're going to have a lot more code to change than what little you have in your actor code. I would much prefer actor.draw(renderer,x,y) than renderer.draw(actor.getAttribs(),x,y). –  corsiKa Jun 25 '11 at 6:18
    
Good answer! Well "You shall not violate the single responsibility principle" is not inside my decalogue, but is still a good principle to take into account –  FxIII Jun 25 '11 at 22:31

The Visitor Pattern can be useful here.

What you can do is have a Renderer interface that knows how to draw each object and a "draw yourself" method in each actor that determines which (specific) renderer method to call, e.g.

interface Renderer {
    void drawPaddle(Player owner, Rectangle position);
    // Note: the Renderer chooses the Color based on which player the paddle belongs to

    // Also drawBackground, drawBall etc.
}

interface Actor {
    void draw(Renderer renderer);
}

class Paddle implements Actor {
    void draw(Renderer renderer) {
        renderer.drawPaddle(this.owner, this.getBounds());
    }
}

This way it is still easy to port to another graphics library or framework (I once ported a game from Swing/Java2D to LWJGL and was very glad I had used this pattern instead of passing a Graphics2D around.)

There is another advantage: The renderer can be tested separately from any actor code

share|improve this answer

In your example you'd want to have the Pong objects implement draw() and render themselves.

Though you won't notice any significant gains in a project of this size, generally separating game logic and their visual representation (rendering) is a worthwhile activity.

By this I mean you'd have your game objects that can be update()'d but they have no idea of how they're rendered, they're concerned only with the simulation.

Then you'd have a PongRenderer() class that has a reference to a Pong object, and it then takes charge of rendering the Pong() class, this could involve rendering the Paddles, or having a PaddleRenderer class to take care of it.

The separation of concerns in this case is a fairly natural one meaning your classes can be less bloated, and it's easier to modify how things are rendered, it no longer has to follow the hierarchy that your simulation does.

share|improve this answer

If you were to do it in the Pong's draw(), you wouldnt' need to duplicate the code -- simply call the Paddle's draw() function for each of your paddles. So in your Pong's draw() you'd have

humanPaddle.draw();
compPaddle.draw();
share|improve this answer
    
Yeah, I knew that, I was just wondering if it was a good idea or not. –  alex Jun 25 '11 at 2:34
    
I guess I got confused because of "If it were in the Pong's draw(), I'd need to write similar code twice." –  Benixo Jun 25 '11 at 4:18
    
My bad :) –  alex Jun 25 '11 at 7:17

Every object should contain its own draw function which should be called by the game update code or draw code . Like

class X
{
  public void Draw( )
  {
     // Do something 
  } 
}

class Y
{
  public void Draw( )
   { // Do Something 
   } 
}

class Game
{
  X objX;
  Y objY;

  @Override
  public void OnDraw( )
  {
      objX.Draw( );
      objY.Draw( ); 
  } 
}

This is not a code but just for showing , how drawing objects should be done.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.