0

I have a game that has two modes: timed limited and stock limited (kinda like smash bros). In my game loop, a method called renderGame() is called which updates moving objects display coordinates and then calls repaint().

@Override
public synchronized void paint(Graphics g) {
   super.paintComponent(g);

   Graphics2D g2d = (Graphics2D) g;

 //Background Image
   g2d.drawImage( displayBackground, 0, 0, null );

 //Stage Image
   g2d.drawImage( displayMap, 0, 0, null );

 //Players Images
   for( Player p: players ){
      if( p.getPlayerNumber() == 1 )
         g2d.drawImage( displayMario, p1XDisplayCoord, p1YDisplayCoord, null);
      else
         g2d.drawImage( displayLuigi, p2XDisplayCoord, p2YDisplayCoord, null);
    }

 //Not implemented yet  
   drawHUD( g2d );

   g2d.dispose();
}

My question is: how can I make it so that the drawHUD() method will draw different things based on the current progression within the match without having to test for the conditions that define that state every time I call renderGame() in my game loop? Kinda like a railway switch.

For example: It should draw a 'ready-set-go' sequence during startup, player stats during gameplay, and it should indicate a match winner once the match has ended. It should also be game type dependent. ex: display a timer that will increment during a stock match, but decrement during a timed match.

hjl
  • 15
  • 6
  • 1
    You could supply different classes which have a "draw" method which simply draw the features you need for the specific implementation, then you can just change which instance you use based on your needs – MadProgrammer May 01 '16 at 22:54
  • @MadProgrammer I think I knew it could be done that way, but I was trying to find a lower level solution that didn't involve new classes. – hjl May 01 '16 at 23:09
  • Then you always need to do some kind state check :P – MadProgrammer May 01 '16 at 23:12
  • @MadProgrammer I see. – hjl May 02 '16 at 00:35

1 Answers1

1

Big issues:

  • You're overriding paint and yet calling the super.paintComponent -- that is a very dangerous thing to do. Instead paintComponent and call the same super's method.
  • You're disposing of a Graphics object given to you by the JVM, another very dangerous thing to do since it completely breaks the graphics chain. Don't do this, but instead only dispose of a Graphics object that you yourself create.
  • Swing is single threaded and so there's no reason to synchronize paint or paintComponent, and risk if you do.

Re:

My question is: how can I make it so that the drawHUD() method will draw different things based on the current progression within the match without having to test for the conditions that define that state every time I call renderGame() in my game loop? Kinda like a railway switch.

Most state checks shouldn't be expensive, but if any are, you can use a boolean switch of some kind that is set if the state changes, which the painting method can test and then reset.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Thanks for pointing out those issues - I'm just getting into graphics and I don't know much. But just to clarify your answer - I can't avoid some sort of test? – hjl May 01 '16 at 21:21
  • You could also have different classes (from a common interface or class) which render the different states, as an idea +1 non the less – MadProgrammer May 01 '16 at 22:56
  • @hjl *Somehow* it must be determined. What he's saying is that there's nothing to optimize as those test are most probably much faster than the painting itself. Don't optimize what doesn't need to. +++ In case it's slow (measure!), you can do such a check from time to time (e.g. every 10 paints) and store the result. Or store the result when an event happens, e.g., the game starts. – maaartinus May 01 '16 at 22:57
  • @maaartinus I just thought that the constant testing for a state that's only gonna change about three times per match seemed highly unnecessary. But if it really is inconsequential then I guess I won't change anything. – hjl May 01 '16 at 23:14