Search code examples
javabufferedimagegraphics2d

multiple graphics2d


ok i have two classes similar like this(the graphics are set up the same way) and another class that is displayed on the bottom. as you can see i have two graphics2ds that i would like to display at the same time with the items class being transparent and on top (the items class has almost nothing in it, and the game class is fully covered with pictures and such)

is there any way to do this?

currently the items class take priority ever the game class because it was called last and totally blocks the game class.

public class game extends Canvas implements Runnable
{

public game()
{
     //stuff here


    setBackground(Color.white);
    setVisible(true);

    new Thread(this).start();
    addKeyListener(this);
}

public void update(Graphics window)
{
   paint(window);
}

public void paint(Graphics window)
{
    Graphics2D twoDGraph = (Graphics2D)window;

    if(back==null)
       back = (BufferedImage)(createImage(getWidth(),getHeight()));

    Graphics graphToBack = back.createGraphics();

//draw stuff here

    twoDGraph.drawImage(back, null, 0, 0);
}


public void run()
{    
try
{

while(true)
    {
       Thread.currentThread();
       Thread.sleep(8);
        repaint();
     }
  }catch(Exception e)
  {
  }
}

}

class two

public class secondary extends JFrame
{
private static final int WIDTH = 800;
private static final int HEIGHT = 600;

public secondary()
{
    super("Test RPG");
    setSize(WIDTH,HEIGHT);

    game game = new game();
    items items = new items();

    ((Component)game).setFocusable(true);
    ((Component)items).setFocusable(true);
    getContentPane().add(game);
    getContentPane().add(items);

    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public static void main( String args[] )
{
    secondary run = new secondary();

}
}

Solution

  • Here are my suggestions:

    • Extend JComponent rather than Canvas (you probably want a lightweight Swing component rather than a heavyweight AWT one)
    • Then don't bother with the manual back-buffering for your drawing - Swing does back-buffering for you automatically (and will probably use hardware acceleration while doing so)
    • Have one component draw both items and the rest of the game background. There is no good reason to do it separately (even if you only change the items layer, the background will need to be redrawn because of the transparency effects)
    • Capitalise Your ClassNames, it makes my head hurt to see lowercase class names :-)

    EDIT

    Typically the approach would be to have a class that represents the visible area of the game e.g. GameScreen, with a paintCompoent method as follows:

    public class GameScreen extends JComponent {
      ....
    
      public void paintComponent(Graphics g) {
        drawBackground(g);
        drawItems(g);
        drawOtherStuff(g); // e.g. animated explosions etc. on top of everything else
      }  
    }