5

I'm making a game in a java applet and I'm trying to optimise my code to reduce flickering.

I've already implemented double buffering, so I'm trying to use another BufferedImage in order to store a picture of the elements of the game's background that don't change. Here's the relevant portion of my code...

public class QuizApplet extends Applet
{
//The image I'm trying to use to store components of the game's gui that don't change within a game
private BufferedImage QBuffImg = new BufferedImage(700,550,2);
private Graphics2D QBuffG2 = QBuffImg.createGraphics();

//The image I use to double buffer
private final BufferedImage drawTo = new BufferedImage(700,550,2);
private final Graphics2D bufferG2 = drawTo.createGraphics();

public void paint(Graphics g)
{
    bufferG2.drawImage(bg, 0, 0, this);


    if(gamescreen == 1)
    {

        paintGameFrame(bufferG2);
        g.drawImage(drawTo, 0, 0, this);
    }
}

//This paints all of the elements of the gui that change with each question
private void paintGameFrame(Graphics2D g2)
{
g2.setColor(Color.BLACK);
g2.setFont(font1);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,          RenderingHints.VALUE_ANTIALIAS_OFF); 
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);

//Drawing the non changing components
g2.drawImage(QBuffImg, 0, 0, this);

g2.drawImage(getImage(getCodeBase(),currentQ.getFigure().getImgLoc()),78,177,this);
printStringInBox(String.valueOf(Qnumber),font2, g2, 6,71,48, 113,true);
printStringInBox("Score: "+person.getScore(),font1,g2,10,8,210,55,false);
printStringInBox("Time: "+String.valueOf(qTimer),font1,g2,475,8,675,55,true);
printStringInBox(currentQ.getQuerry(),font1,g2,80,68,622,118,true);
printStringInBox(currentQ.getFigName(), font2, g2, 50, 425, 265, 470,true);
printStringInBox(pos1.getChoice().getText(), font2, g2, pos1.getX1()+20, pos1.getY1(), pos1.getX2()-20, pos1.getY2(),true);
printStringInBox(pos2.getChoice().getText(), font2, g2, pos2.getX1()+20, pos2.getY1(), pos2.getX2()-20, pos2.getY2(),true);
printStringInBox(pos3.getChoice().getText(), font2, g2, pos3.getX1()+20, pos3.getY1(), pos3.getX2()-20, pos3.getY2(),true);
printStringInBox(pos4.getChoice().getText(), font2, g2, pos4.getX1()+20, pos4.getY1(), pos4.getX2()-20, pos4.getY2(),true);
printStringInBox("Multiplier: x"+String.valueOf(Math.round((difflevel+.10*multiplier)*10)/10.0), font1, g2, 245, 496, 458, 550, true);
if(waiting)
{
    g2.drawImage(right_wrongPic, lastChoicePos.getX1()-30,lastChoicePos.getY1()-12,this);
}
}

private void initializeDiffVars()
{   

QBuffG2.setColor(Color.BLACK);
QBuffG2.setFont(font1);
QBuffG2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); 
QBuffG2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); 
QBuffG2.drawImage(frame, 24, 124, null);
QBuffG2.drawImage(framebg, 29, 130, null);
QBuffG2.drawImage(stick, (getWidth()/3)-2, -9, null);
QBuffG2.drawImage(stick, (2*getWidth()/3)-2, -9, null);
QBuffG2.drawImage(stick, getWidth()/3, getHeight()-54, null);
QBuffG2.drawImage(stick, (2*getWidth()/3)-2, getHeight()-54, null);
QBuffG2.drawImage(nameBG, 20, 430, null);
QBuffG2.drawImage(querrybg, 50,68,null);
QBuffG2.drawImage(querrybg, 50,68,null);
QBuffG2.drawImage(Qbg, pos1.getX1(), pos1.getY1(), null);
QBuffG2.drawImage(Qbg, pos2.getX1(), pos2.getY1(), null);
QBuffG2.drawImage(Qbg, pos3.getX1(), pos3.getY1(), null);
QBuffG2.drawImage(Qbg, pos4.getX1(), pos4.getY1(), null);
printStringInBox(person.getName(),font1,QBuffG2,243,8,451,55,true);
printStringInBox(String.valueOf(NUMQUESTIONS),font2, QBuffG2, 655,71,697,113, true);
printStringInBox("High Score: "+highScoreDisp, font1, QBuffG2, 5, 495, 227, 550, true);
printStringInBox("New Game",font1,QBuffG2,newGame.getX1(),newGame.getY1(),newGame.getX2(),newGame.getY2(),true);

repaint();
}

}

So when I have all of these draw commands in the paintGameScreen() method it works fine, aside from the flickering, but when I split it up like this, none of the images drawn in initializeDiffVars() show up, but the text does. If anyone could help it would be greatly appreciated.

Ryan Stull
  • 1,056
  • 14
  • 35
  • 1
    My guess: The images in question haven't loaded by the time initializeDiffVars runs. But when the painting is redone every they are painted because they quickly load. Hard to say without seeing how these images are loaded. – Lawrence Dol Jun 03 '11 at 03:52

1 Answers1

3

I'd extend JApplet and use JPanel, which is double buffered by default, for the content. If you're trying to limit the update area, you might look into getSubimage(), shown here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Ok, so would I essentially do the same thing with a JComponent in place of the buffered image. Can you paint to a Jcompnent the same way you can to a buffered image? And do I still use the paint() method of the JApplet() or do I use update(), and what's the difference? Sorry to ask so many questions, I'm just unfamiliar with Jcompnents and the like. – Ryan Stull Jun 04 '11 at 22:58
  • I prefer `JPanel` (a subclass of `JComponent`) for the content pane, as it uses the platform's `PanelUI`. For either, override `paintComponent()` instead of `paint()`, as mentioned [here](http://java.sun.com/products/jfc/tsc/articles/painting/index.html#callbacks) and shown in this [example](https://sites.google.com/site/drjohnbmatthews/subway). – trashgod Jun 05 '11 at 00:27