Basic Technologies: There are many ways to achieve animations in Java, but the basic principles they achieve are the same, that is, draw a series of frames to create a feeling of motion on the screen. Let's construct a program framework, slowly expand, make it more complete.
Use thread: For multiple update screens per second, you must create a thread to implement a loop of the animation, this loop to track the current frame and respond to periodic screen update requirements. There are two ways to implement threads, you can create a derived class of THREAD, or attached to the interface of Runnable. An easy-to-criminal error is to loop the animation in Paint (), which occupies the primary AWT thread, and the main thread will be responsible for all drawings and event processing. A frame applet follows: public class Animator1 extends java.applet.Applet implements Runnable {int frame; int delay; Thread animator; public void init () {String str = getParameter ( "fps"); int fps = (str = null! )? INTEGER.PARSEINT (STR): 10; DELAY = (fps> 0): 100;} public vois start () {Animator = New Thread (this); Animator.Start ();} public () Void Run () {while (thread.currentthread () == Animator) {repaint (); try {thread.sleep (delay);} catch (interruptedException e) {Break;} frame ;}} public void stop ()} Animator = null;}} In your HTML file, this reference is called:
Keep a constant frame speed: In the above example, the applet is only a fixed time between each two frames, but this has some shortcomings, sometimes you will wait a long time, for a ten frame image per second, should not sleep 100 Mixi, because there is time in operation. Here is a simple remedy: public void run () {long tm = system.currenttimemillis (); while (thread.currentthread () == animator) {repaint (); try {tm = delay; thread.sleep Math.max (0, TM - System.currentTimeMillis ()));} catch (interruptedException e) {Break;} frame ;}}
Draw each frame: The rest is to draw each frame image. The Applet repainT () is called in the above example to draw each frame image. Public Void Paint (Graphics G) {g.setcolor (color.black); g.drawstring ("frame" frame, 0, 30);} Generate graphics: Now let's draw some slightly difficult things. The next example draws a combination of sinusoidal curves, for each X, painted a short vertical line, all of which makes a graphic, and each frame changes. But unfortunate some flashing, after we will explain why flashes and how to avoid it. Public Void Paint (Graphics G) {Dimension D = Size (); INT H = D.Height / 2; for (int x = 0; x Avoid flashing: Two reasons in the flash in the above example: Draw a time for each frame (because the amount of calculation required during the redraw is large), the second is cleared in front of each time () before, When the calculation of the next frame is performed, the user sees the background. The short time to clear the background and draw the graph is being seen by the user, it is flashing. In some platforms, such as the PC, it is obvious than the X WINDOW, because the image of X WINDOW is cached, making the flashing time relatively short. There are two ways to significantly lose glitter: overload Update () or use double buffer. 1. Overload Update () When the AWT receives an applet's redraw request, it calls the applet's update (). By default, update () clears the background of the applet and calls Paint (). Update (), the drawing code previously previous () is included in the Update (), thereby avoiding the entire area when redrawing. Since the background is not automatically cleared, we need to complete it in Update (). We erase vertical lines alone before drawing new lines, completely eliminated flashing. Public Void Paint (Graphics G) {Update (G);} public void update (graphics g) {color bg = getBackground (); dimension D = size (); int h = d.Height / 2; for (int x = 0; x% lt; d.Width; x ) {int y1 = (int) ((1.0 math.sin ((x - frame) * 0.05)) * h); int y2 = (int) ((1.0 Math.sin ((x frame) * 0.05)) * h); if (Y1> Y2) {INT T = Y1; Y1 = Y2; Y2 = T;} g.SetColor (BG); g.drawline (x , 0, x, y1); g.drawline (x, y2, x, d.height); g.setcolor (color.black); g.drawline (x, y1, x, y2);}} 2. Double buffer technology: Another method of flickering between frames is to use dual buffers, which are used in many animation applets. The main principle is to create a background image, draw a frame into the image, then call DrawImage () draws the entire image once on the screen. The advantage is that most of the drawings are away from the screen. Painting the off-screen image to the screen is much more effective than drawing it directly on the screen. Double buffer can make the animation smooth, but there is a shortcoming, to assign a background image, if the image is quite large, this will require a big memory. Update () should be overloaded when you use double buffer technology. Dimension offDimension; Image offImage; Graphics offGraphics; public void update (Graphics g) {Dimension d = size ();! If ((offGraphics == null) || (d.width = offDimension.width) || (d.height ! = offDimension.height)) {offDimension = d; offImage = createImage (d.width, d.height); offGraphics = offImage.getGraphics ();} offGraphics.setColor (getBackground ()); offGraphics.fillRect (0, 0 , d.Width, D.Height; offgraphics.setColor (color.black); PaintFrame (offgraphics); g.drawImage (Offimage, 0, 0, null);} public void Paint (Graphics G) {IF (Offimage! = NULL) {g.drawImage (OFFIMAGE, 0, 0, NULL);}} public void PaintFrame (GRAPHICS G) {Dimension D = Size (); int h = d.Height / 2; for (int x = 0; x Moving an image on the screen: World.gif As the background, Car.gif acts as a moving object, and is drawn twice, causing a two cars game. Image world; image car; public void init () {string str = getParameter ("fps"); int FPS = (STR! = Null)? Integer.Parseint (STR): 10; DELAY = (FPS> 0)? 1000 / fps): 100; World = GetImage (getCodeBase (), "world.gif"); car = getimage (getCodeBase (), "car.gif");} public void Paint (Graphics g) {Update (g) } public void PainTframe (graphics g) {Dimension D = size (); int w = world.getwidth (this); int h = world.getHeight (this); if ((w> 0) && (h> 0) ) {G.drawImage (world, (D.Width - W) / 2, (D.HEIGHT - H) / 2, this);} w = car.getwidth (this); h = car.getheight (THIS); IF ((w> 0) && (h> 0)) {w = d.width; g.drawImage (car, d.width - (Frame * 5)% w), (D.Height - h) / 3, this); g.drawImage (CAR, D. Width - ((Frame * 7)% W), (D.Height - h) / 2, this);}} Display a series of images: through each frame Display an image to create an animation. We still use a double buffer method to reduce flicker. The reason is that some of the images we have displayed are transparent, so it is necessary to remove the current erase the current, if the technique that does not use double buffer will cause flashing. Image frame []; public void init () {string str = getParameter ("fps"); int FPS = (STR! = Null) Integer.Parseint (STR): 10; DELAY = (fps> 0)? (1000 / fps): 100; frames = new image [10]; for (int i = 0; i <10; i ) {frames [i] = getImage (), "duke / t" i ".gif ");}} Public void Paint (Graphics g) {Update (g);} public void PaintFrame (graphics g) {g.drawimage (frames [frame% 10], 0, 0, null);}