Hi,
I’m slowly getting into this Java game development, and now I have some time so I can discover how double-buffering is done. I’ve got some code from a tutorial, and my application draws a blue square on the screen without flickering. This all works, but I have a couple of “why is this like this” questions ;D
OK, first the constructor. It creates an application frame which displays a window. It also adds a mouse motion listener, so when the mouse is moved the blue rectangle follows the mouse position. I also added that if the graphics environment is faulty the program should exit.
The next thing I do is to create the Offscreen Image, and here is where the problem starts. Look at the code:
public class DrawTest extends ApplicationFrame implements MouseMotionListener
{
public int mx,my;
public volatile Image Offscreen;
public DrawTest()
{
super("Double-buffered drawing",300,300);
addMouseMotionListener(this);
if (GraphicsEnvironment.isHeadless()) System.exit(1);
// create Offscreen
Dimension d = getSize();
if ( (Offscreen == null) ||
(Offscreen.getWidth(null) != d.width) ||
(Offscreen.getHeight(null) != d.height) )
{
Offscreen = createImage(d.width, d.height);
}
// if (Offscreen == null) System.exit(2);
// start
setVisible(true);
}
OK, now let’s say I uncomment that line with Offscreen being null. Then the application will exit. The Offscreen was not created! Why?
I also use an Image and not a BufferedImage. I’ve read somewhere that BufferedImage is a lot better cause it allows access to pixels. Is this true?
OK, then goes the paint() mathod. This works ok, I just want to clarify one thing. At the end of the paint() method, I will call repaint() so that the image would be painted again. Will this cause the current procedure to be placed on the stack, and a new paint() to be called? Then that one will call repaint() again, be placed on the stack, and so on. Or will everything be fine? I ran the application for a while like this, I also tracked its memory usage and it worked just fine, it even decreased its memory usage after a while. Does this mean I can safely put repaint() at the end of the paint() method, or perhaps I should create a loop and call repaint() from there all the time?
public void paint(Graphics g)
{
Dimension d = getSize();
// check if offscreen is available
if ( (Offscreen == null) ||
(Offscreen.getWidth(null) != d.width) ||
(Offscreen.getHeight(null) != d.height) )
{
Offscreen = createImage(d.width, d.height);
}
// clear the offscreen
Graphics OffG = Offscreen.getGraphics();
OffG.setColor(getBackground());
OffG.fillRect(0,0,d.width,d.height);
// draw on the offscreen image
int s = 100;
OffG.setColor(Color.BLUE);
OffG.fillRect(mx - s/2, my - s/2, s, s);
// put the offscreen on the screen
g.drawImage(Offscreen,0,0,null);
// force another repaint
repaint();
}
public void update(Graphics g)
{
paint(g);
}