Buffered Java Animation
To eliminate the flicker problem we will have to use a technique that holds a copy of the Java screen in a buffer in memory. We will then make all the changes to the 'buffer' screen and then simply copy the buffered screen to the output screen. The steps are outlined in the diagram below.
The output screen is never cleared. It is replaced by the updated screen in one single action. This is just like a motion picture. There is no point in time where the screen is blank and therefore no flicker.
The code we used in the flickering
version can be used with some minor variations:
1) An
off screen 'buffered' image needs to be created and enabled
2)
Override the screen update method to simply call the paint method
and NOT clear the screen.
3)
Make all image changes to the buffered copy of the screen
4)
Copy the buffer to the output screen
The code changes to accomplish these tasks aren't very difficult as you can see below.
| import java.awt.Graphics; import java.awt.Color; import java.awt.Font; import java.awt.Image; public class marque2 extends java.applet.Applet implements Runnable { String mesag ="Scrolling text is a simple animation. Just draw the text, wait a while and then redraw it one pixel to the left!"; Font mfont = new Font("TimesRoman",Font.BOLD, 24); int Xposition = 600; Thread runner; |
This code remains the same as the last example | |
| 1) | Image scrnBuf; Graphics scrnG; |
Until this point where we create a Buffer scrnBuf to hold a copy of our output screen and enable the graphics methods for that screen |
| 1) | public void init() { scrnBuf = createImage(600,50); scrnG = scrnBuf.getGraphics(); } |
The screen buffer needs to be initialized to the size of our output screen and be capable of performing the same graphic methods. |
| public void start() { if (runner == null); { runner = new Thread(this); runner.start(); } } |
We still need to start and... | |
| public void stop() { if (runner != null); { runner.stop(); runner = null; } } |
Stop our threads as before. | |
| public void run() { while(true) { repaint(); try {Thread.sleep(30);} catch(InterruptedException e) { } } } |
And follow the same overall method of repainting the screen, sleeping for a while and checking for errors |
|
| 2) | public void update(Graphics g) { paint(g); } |
It is very important that we override the update
method which is automatically called by repaint to simply call paint and not clear the screen. One of the strengths of Java classes is that we can override any of them to achieve the desired effect. |
| 3) 4) |
public void paint(Graphics g)
{
scrnG.setColor(Color.white);
scrnG.fillRect(0,0,600,50);
scrnG.setColor(Color.red);
scrnG.setFont(mfont);
scrnG.drawString(mesag,Xposition,35);
Xposition--;
if (Xposition < -1200)
{
Xposition = 600;
}
g.drawImage(scrnBuf, 0 , 0 , this);
}
}
|
This is where all the work is done on our buffer
screen remember scrnG. can use the same methods as g. so... First set the color of the buffer screen to white Draw a filled rectangle to clear it of the last image set the color of the text and draw the string on the screen at its new position. check to see if it has scrolled off the screen as before and then put the new image on the output screen using the drawImage method we covered two sections back. |
The easiest way to copy the code for this example is to click here, copy the contents of the screen that loads in your browser , paste it in a text editor and save it in a file called "marque2.java".
After compiling this program we need to create an HTML page with a reference to the class file. It must run in a graphic window that is large enough to accomodate the pixels in the grid. The following HTML Code will meet all the requirements.
| <html> <head> <title>Applet Page</title> </head> <p align="left"><font size="6"> <strong>View of the applet's output</strong></font></p> <p><applet code="marque2.class" align="baseline" width="600" height="50"></applet></p> </body> </html> |
<This line places a label above the applet The Applet is inserted here with a window of 600 pixels in height and 50 in width. |
Save the HTML code in the same directory as the class file.
When you load the HTML file in your browser the applet will execute within the window. The results should resemble what you see below.
View of the applet's output
Notice that the output is the same but the flicker is gone. This code can be used as a template to animate any image. We will say 'goodbye' to graphics by using this code to animate the Java Duke images we covered in a previous section incorporating sound.