CATEGORII DOCUMENTE |
Asp | Autocad | C | Dot net | Excel | Fox pro | Html | Java |
Linux | Mathcad | Photoshop | Php | Sql | Visual studio | Windows | Xml |
Creating Animation
Like the final voyage of the S.S. Minnow, the trip through
the visual side of Java programming is a three-hour tour. At this point, you
have learned how to use text, fonts, color, lines, and polygons in your Java
applets. Any adversity you have experienced should have been minor, at least in
comparison to the castaways of Gilligan's
This third hour shows how to display image files in the .GIF and .JPG formats in your applets and some tricks to use when presenting these images in an animation. The following topics will be covered:
Using Image objects to hold image files
Putting a series of images into an array
Cycling through an image array to produce animation
Using the update() method to reduce flickering problems
Using the drawImage() command
Drawing to an off-screen workspace
Why double-buffering improves animation results
Establishing rules for the movement of an image
Creating an Animated Logo Applet
Computer animation at its most basic consists of drawing an image at a specific place, moving the location of the image, and telling the computer to redraw the image at its new location. Many animations on Web pages are a series of image files, usually .GIF or .JPG files, that are displayed in the same place in a certain order. You can do this to simulate motion or to create some other effect.
The first program that you will be writing today uses a series of image files for an animated logo. Several details about the animation will be customizable with parameters, so you can replace any images of your own for those provided for this example. Create a new file in your word processor called Animate.java. Enter Listing 18.1 into the file, and remember to save the file when you're done entering the text.
Listing 18.1. The full text of Animate.java.
1: import java.awt.*;
2:
3: public class Animate extends java.applet.Applet implements Runnable else
break;
}
String pauseText = null;
pauseText = getParameter('pause');
if (pauseText != null)
}
public void paint(Graphics screen)
public void start()
}
public void run()
catch (InterruptedException e)
}
}
public void stop()
}
public void update(Graphics screen)
This program uses the same threaded applet structure that you used during Hour
14, 'Creating a Threaded Applet.' Threads are often used during
animation programming because they give you the ability to control the timing
of the animation. The Thread.sleep() method is an effective way to
determine how long each image should be displayed before the next image is
shown.
The Animate applet retrieves images as parameters on a Web page. The parameters should have names starting at 'image0' and ending at the last image of the animation, such as 'image3' in this hour's example. The maximum number of images that can be displayed by this applet is 6, but you could raise this number by making changes to Lines 5 and 12.
The totalPicture integer variable determines how many different images will be displayed in an animation. If fewer than 6 image files have been specified by parameters, the Animate applet will determine this during the init() method when imageText equals null after Line 14.
The speed of the animation is specified by a pause parameter. Because all parameters from a Web page are received as strings, the Integer.parseInt() method is needed to convert the text into an integer. The pause variable keeps track of the number of milliseconds to pause after displaying each image in an animation.
Preventing Flickering Animation
As with most threaded programs, the run() method contains the main part of the program. A while (true) statement in Line 40 causes Lines 41-46 to loop as long as the program is not stopped by someone leaving the Web page.
The first thing that happens in the run() method is a repaint(); statement. This statement causes the update() method and paint() method to be handled, in that order, so that the screen can be updated. Use repaint() any time you know something has changed and the display needs to be changed to bring it up to date. In this case, every time the Animate loop goes around once, a different image should be shown.
The update() method contains only one statement, paint(screen);. The reason to use this method is that it overrides the behavior that update() normally performs. If you did not override update() in the Animate program, it would clear the screen before calling on the paint() method. This action causes flickering animation problems that have been mentioned in previous hours.
Loading and Displaying Images
The paint() method is simple in this applet: It draws an image on-screen with the drawImage() method. The drawImage() method displays a current Image object at the (x, y) position specified. The following is another example of a drawImage() statement:
screen.drawImage(turtlePicture, 10, 25, this);
This statement displays the Image object called turtlePicture at the (x, y) coordinates of (10, 25). The this statement sent as the fourth argument to drawImage() enables the program to use a class called ImageObserver. This class tracks when an image is being loaded and when it is finished. The Applet class contains behavior that works behind the scenes to take care of this process, so all you have to do is specify this as an argument to drawImage() and some other methods related to image display. The rest is taken care of for you.
The preceding example assumed that an Image object called turtlePicture had been created and loaded with a valid image. The way to load an image in an applet is to use the getImage() method. This method takes two arguments, the Web address or directory that contains the image file and the file name of the image.
The first argument is taken care of with the getCodeBase() method, which is part of the Applet class. This method returns the location of the applet itself, so if you put your images in the same directory as the applet's class file, you can use getCodeBase(). The second argument should be a .GIF file or .JPG file to load. The following statement loads the turtlePicture object with a file called Mertle.gif:
Image turtlePicture = getImage(getCodeBase(), 'Mertle.gif');
Storing a Group of Related Images
In the Animate applet, images are loaded into an array of Image objects called pictures. The pictures array is set up to handle six elements in Line 5 of the program, so you can have Image objects ranging from picture[0] to picture[5]. The following statement in the applet's paint() method displays the current image:
screen.drawImage(picture[current],0,0,this);
The current variable is used in the applet to keep track of which image to display in the paint() method. It has an initial value of 0, so the first image to be displayed is the one stored in picture[0]. After each call to the repaint() statement in Line 41 of the run() method, the current variable is incremented by one in Line 42.
The totalPictures variable is an integer that keeps track of how many images should be displayed. It is set when images are loaded from parameters off the Web page. When current equals totalPictures, it is set back to 0. As a result, current cycles through each image of the animation, and then begins again at the first image.
Sending Parameters to the Applet
Becaus the Animate applet relies on parameters to specify the image files it should display, you need to create a Web page containing these file names before you can test the program. After saving and compiling the Animate.java file, open up a new file in your word processor and call it Animate.html. Enter Listing 18.2 into that file, and save it when you're done.
Listing 18.2. The full text of Animate.html.
1: <applet code='Animate.class' width=230 height=166>
2: <param name='image0' value='sams0.gif'>
3: <param name='image1' value='sams1.gif'>
4: <param name='image2' value='sams2.gif'>
5: <param name='image3' value='sams3.gif'>
6: <param name='pause' value='400'>
7: </applet>
This file specifies four image files: sams0.gif, sams1.gif,
sams2.gif,
and sams3.gif.
These files are listed as the values for the parameters image0 through image3.
You can find the files used in this example on this book's CD-ROM in the
directory Win95nt4/Book/Source/Hour18.
They also can be downloaded from the book's official Web site at the following
address:
<https://www.prefect.com/java24>
Look for the Hour 18's graphics link that's available on the main page of the site. You also can specify any of your own .GIF or .JPG files if desired. Whichever files you choose should be placed in the same directory as the Animate.class and Animate.html files. With the 'pause' parameter, you can specify how long the program should pause after each image is displayed.
You might be wondering why the files and the parameters are given names that start numbering with 0 instead of 1. This is done because the first element of an array in a Java program is numbered 0. Putting an image0 called sams0.gif into pictures[0] makes it easier to know where these images are being stored.
Once the files have been put in the right place, you're ready to try out the Animate applet. Type the following command to use the appletviewer to view the page:
appletviewer Animate.html
Figure 18.1 shows the four images of the animation that was provided for this book.
Figure 18.1. <../art/18/18tja01.jpg> Four shots of the Animate applet as it runs.
Although this is a simple animation program, hundreds of applets on the Web use similar functionality to present a series of image files as an animation. Presenting a sequence of image files through Java is similar to the animated .GIF files that are becoming more commonplace on Web pages. Although Java applets are often slower to load than these .GIF files, applets can provide more control of the animation and allow for more complicated effects.
Workshop: Follow the Bouncing Ball
This hour's workshop is an animation that definitely couldn't be replicated with an animated .GIF file or any other non-programming alternative. You'll write a program that bounces a tennis ball around the screen in lazy arcs, caroming off the sides of the applet window. Though a few laws of physics will be broken along the way, you'll learn one way to move an image file around the screen.
Create a new file in your word processor called Bounce.java, and enter the text of Listing 18.3 into it. Save and compile the file when you're done.
Listing 18.3. The full text of Bounce.java.
1: import java.awt.*;
2:
3: public class Bounce extends java.applet.Applet implements Runnable
public void paint(Graphics screen)
public void start()
}
public void run()
catch (InterruptedException e)
}
}
public void stop()
}
public void update(Graphics screen)
Before you dive into the discussion of what's taking place in this applet, you
should see what it does. Create a new file in your word processor called Bounce.html
and enter Listing 18.4 into it.
Listing 18.4. The full text of Bounce.html.
1: <applet code='Bounce.class' width=500 height=300>
2: </applet>
After saving this file, you need to get a copy of the tennis.jpg file
and put it in the same directory as Bounce.class and Bounce.html.
This file is available from the same place as the Sams.net logo image files:
the /Win95nt4/Source/Hour18
directory of the CD-ROM and the book's Web site at
<https://www.prefect.com/java24>. Once you have copied tennis.jpg
into the right place, use appletviewer or a Java-enabled Web browser to display
this program. Figure 18.2 shows the Bounce applet running on
Netscape Navigator.
Figure 18.2. <../art/18/18tja02.jpg> The Bounce applet running on a Web page loaded by Netscape Navigator.
This applet displays a .JPG file of a tennis ball bouncing back and forth. It hits a point at the bottom edge of the applet window and rebounds upward close to the top edge of the window. When the ball hits the right or left edge of the window, it bounces in the opposite direction. If you're using appletviewer to try the applet out, resize the window by making the right and left edges smaller. The Bounce applet can keep track of your actions.
The Bounce applet is a relatively simple example of how to animate an image file using Java. It consists of the following steps:
Draw the ball at its current location.
Move the ball according to the rules that have been established for how the ball should move.
Check whether the rules need to be changed based on the ball's new location.
Repeat.
Drawing the Image
The Bounce applet has the same basic structure as the Animate applet. It's a threaded program with start(), stop(), and run() methods to control the operation of the thread. There are also update() and paint() methods to display information on-screen.
The Image object called ball is loaded with the tennis.jpg image in the init() method. Several variables are used in the applet to keep track of the ball's location and its current rate of movement:
xPosition: This variable is the x coordinate where the ball should be drawn. This coordinate begins as 10.
xMove: This variable is the amount that the ball should move along the x axis after every screen update. This amount starts out as 1, but it will change to -1 when the ball hits the right edge of the applet window. It changes back and forth from -1 to 1 every time it hits an edge, and this change is handled by Lines 51-54.
yPosition: This variable is the y coordinate where the ball should be drawn. This coordinate is initially set to -1, which is a signal to the paint() method that the yPosition needs to be set up before the ball can be drawn for the first time. The yPosition value varies from a point near the bottom of the applet window to the top edge.
current: This floating-point number starts at 0 and increases by 0.1 each time the ball is redrawn. When it reaches 3, it is set back to 0 again. The current variable is used with a mathematical sine function to determine how high the ball bounces. Sine waves are a good way to approximate the movements of a bouncing ball, and the Math.sin() method enables a sine value to be used in conjunction with animation. The tennis ball is traveling half a sine wave each time it goes from the ground to the top of the window and back.
The movement rules that you establish for an animation applet will vary depending on what you're trying to show. The Bounce applet uses the Math.sin() method to create the slow arcs traveled by the ball.
Drawing to a Hidden Screen
The paint()method uses a technique called double-buffering to make the animation display more smoothly. Double-buffering is drawing everything off-screen to a storage place that's the same size as the program's display area and copying it to the display only when all drawing is done. The advantage to using double-buffering is that it reduces flickering and other things that might be seen while the paint() method is drawing things on-screen.
Because all drawing in an applet is done to a Graphics object that represents the applet window, you have to create an additional Graphics object for the off-screen area. You also must create an Image object to hold everything that's being drawn to the hidden area. Lines 14-15 create an Image object called workspace and a Graphics object called offscreen. These objects are set up in the init() method. Line 18 uses the createImage() method to set up workspace as an empty image the size and width of the applet window. Line 19 associates the offscreen object with the workspace image, using the getGraphics() method of the Image class.
The key to double-buffering is to draw everything to the off-screen area in the paint() method. To do this, use the offscreen object for all display methods instead of the screen object. Each of these methods will update the workspace image with the things that are being displayed.
When all drawing has been done and you know the off-screen area looks the way the screen should look, draw that entire off-screen image to the applet window by using a statement such as the one on Line 34:
screen.drawImage(workspace, 0, 0, this);
Because workspace is an Image object with the same dimensions as the applet window, you can use (0,0) as its coordinates, and it will fill the display area.
When you are drawing only one image to the screen during each update, as you did in the Animate applet, there's no reason to use double-buffering. However, if the animation involves more than one thing to draw, you will get better results by drawing to an off-screen area and then copying the whole thing to the screen at one time.
The Bounce applet requires an off-screen area because it clears the screen right before drawing the tennis ball during each update. The screen is cleared by drawing a filled white rectangle the size of the applet window. This rectangle is needed to remove the image of the ball in its last position before the new position is drawn.
Summary
Using the classes that come with the Java language, you can produce some interesting animated graphics and games. A lot of graphics functionality is built-in and can be used in short programs like those written during this hour.
Because Java is an interpreted language, its programs run at speeds slower than compiled languages such as C can achieve. This makes it more of a challenge to produce animated graphics at acceptable speeds. However, many applets on display on World Wide Web pages showcase Java's graphics capabilities.
What you have learned about graphics and animation should
keep you from running adrift if you venture into uncharted waters like Java
game programming and other visually inventive projects. Java animation
programming is quite a challenge, but it could be worse. The Professor on
Gilligan's
Q&A
Q Does a
threaded animation program have to use Thread.sleep() to pause, or can you omit
it to produce the fastest possible animation?
A You have
to put some kind of pause in place in an animation program, or the program will
crash or behave erratically. Your applet is running as part of a bigger
program, the Web browser or appletviewer, and that program won't be
able to keep up with constant repaint() requests without the pause. Part of the
process of animation design in Java is finding the right display speed that all
applet-running environments can handle.
Q What happens if you draw something
such as an image to coordinates that aren't within the applet window?
A Methods that draw something to a coordinate will continue to draw it even
if none of it is visible within the area shown by the applet window. To see
this in action, reduce the height of the Bounce applet as it runs in the appletviewer tool. The tennis ball will
drop below the window and bounce back upwards into the window.
Quiz
Animate yourself as much as you can muster and answer the following questions to test your skills.
Questions
Where is the (0,0)
coordinate on an applet window?
(a) In the off-screen
double-buffering area
(b) The exact center of the window
(c) The upper-left corner of the
applet window
2. What thing did you not learn
during this hour?
(a) How to use Graphics and Image objects to create an
off-screen workspace
(b) How to override the update() method to reduce animation
flickering
(c) Why Thurston Howell III and his
wife Lovey packed so much clothing for a three-hour tour
3. In a threaded animation applet,
where should you handle most of the movement of an image?
(a) The run() method
(b) The init() method
(c) The update() method
Answers
c. The x value increases as
you head to the right, and the y value increases as you head downward.
2. c. If the tiny ship had not been so weighted down with smoking jackets
and evening gowns, the Skipper and Gilligan might have been able to outrun the
storm.
3. a. Some movement might be handled
by statements in the paint() method, but most of it will take place in run() or a method called from
within run()
Activities
Before you're stranded and the subject of graphics is abandoned, picture yourself doing the following activities:
Change the Bounce applet so that the ball loses 10 percent of its bouncing strength each time it hits the ground. You can do this by changing the height variable at a certain time within the run() method.
Create an animation applet where the object or objects you move wrap around the edges of the applet window, coming back through the opposite side.
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 1149
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved