Simple Animation

Lab Assignment 4

This assignment introduces you to applets. Applets (“little applications”) differ in several important ways from stand-alone Java applications: they do not have a main method, they are executed by an external process (such as a web browser) and they are usually graphical in nature. They are very handy for embedding programs inside other objects (such as web pages).

You are to turn in a copy of your working Pacman applet and your own animation applet, along with the Web page that calls it, all in a folder as described in Lab Assignment Guidelines and Grading.

Your own animation must use at least three of the Java graphics methods discussed in this lab

Be prepared to give an on-line demonstration of your program, should your TA so request.


Overview

To give you a feel for how graphics and applets work in Java, we first have you modify existing Java code so that Pacman moves through a maze, eating the “power pills” he finds along the way, without touching any of the walls. You don’t need to worry about programming the eating of the pills, as just moving the Pacman over them will erase them. If the Pacman touches any of the walls they will be permanently erased, so you need to steer carefully. In addition, you need to make sure that Pacman’s mouth is always pointing in the direction he is moving; that means you will have to rotate him as you travel.

When you run Pacman, you will note the Power Pill on the extreme right is in a different color than the rest of the Pills, and, on each run of the program, that the position of that Pill changes. We want you to have Pacman change color to pink the instant he touches this particular Power Pill, and stay pink until he completes the maze.

We strongly suggest you get the modified Pacman program working and well documented before moving on to the next part of the assignment. You do need to know how to do the simple things in this program before undertaking your own animation.

Then you are to produce an original animation. We suggest that you begin by making a static drawing, then adding some simple animation elements, then more elaborate ones. This sort of incremental development keeps errors to a minimum, and allows you to review work as you go. To give you an idea of the kinds of things you could do, here is a list of some of the animations students did in previous classes that did (a version of) this assignment:

• A basketball “making” a basket

• A fish tank, with bubbles rising from the fishes’ mouths

• A face which alternately smiled and frowned

• A pair of eyes with pupils that dilated

• A Christmas scene with falling snow

• Barney being run over by a truck!!

Warning:The animation approach used in this assignment may cause the screen to flicker. If flickering of this kind provokes a medical condition you have (such as certain kinds of epilepsy or migraine headaches), stop working on this assignment, and see the instructor, who will arrange an alternative assignment.


About applets

Running an applet:Applets are typically executed by issuing an APPLET command from a Web page. Note the applet has to be a .class file—not a .java file. In other words, applets run Java byte code, not source code. The file Pacman.html (which you can access and download below) describes the APPLET tag and demonstrates its use.

To run an applet, you simply go the the Web page that contains the APPLET tag that invokes the applet. To see how this works, click on the Pacman.html link below; an (incomplete) Pacman applet will run. (Note, though, that it will not run on older browsers, specifically those that do not support the Java Graphics2D package. The browers in lab will run the applet.) To see how the APPLET tag invokes the Pacman applet, look at the Pacman.html source.

Graphics and Graphics2D: Java has built-in graphical objects and operations that make drawing pictures much easier. They work in a graphical context, a Graphics class object that contains all the information needed to keep track of your applet’s graphics. (The Java Applet class constructs this object for you). When an applet is invoked, and whenever the screen in which the graphics context appears needs to be redrawn, it automatically calls the paint() method, passing the graphics context to it.

The Graphics class was the first class Java had to handle graphics; it has since been superseded by Graphics2D, a much more object-oriented, consistent and powerful class. However, to avoid breaking applets written with Graphics objects, Java did not change the type of the graphics context from Graphics to Graphics2D. So, to use Graphics2D objects in your applet—and we do require that you do use them, instead of Graphics methods—you must typecast the context to a Graphics2D object. It is the first thing to do in the paint() method:

public void paint(Graphics g)
{
  Graphics2D g2 = (Graphics2D)g;
...
}

Then, throughout the rest of your code, use g2 instead of g.

The applet coordinate system: Java uses a system based on the Cartesian coordinate system. The origin of the system is the top, left-hand corner of the graphics context. The value of x increases as we move to the right; the value of y increases as we move down. For example, the following lines of code produce the output shown in Figure 1.

Line2D.Double thisLine = new Line2D.Double(0,0,200,100);   // Build a line
g.draw(thisLine);   // Draw a line
g.drawString("Monty Python",240,150);   // Write some text
Ellipse2D.Double oval = new Ellipse2D.Double(280,30,40,35);   // Build an oval
g.draw(oval);   // Draw the oval
RoundRectangle2D.Double roundRect =
  new RoundRectangle2D.Double(40,130,60,50,5,5);  //Build a rectangle with rounded corners
g.fill(roundRect);  // Draw a rounded rectangle filled in with the current color (default is black)

Figure 1



Another example: here’s a picture of Pacman just before he begins negotiating the maze:

The Pacman is centered at [40,260]. That is to say, his center is located 40 units from the left, and 260 down from the top.

How to animate inside an applet: All drawing commands must be called, directly or indirectly, from paint(). We can put the drawing commands directly in paint(), or place the drawing commands in other methods, and call them from paint(). We strongly suggest you do the latter. The Pacman example demonstrates this approach. Note we have one method call drawMaze(), and another called drawPacman(), both of which are called from paint().

drawPacman() has 5 parameters. The first is the graphics environment. The next two control the location in which the Pacman is drawn. The third controls the angle of his mouth in degrees, with 0 indicating facing right, 90 meaning pointing upward, etc. The forth parameter controls the color of the Pacman.

Once we have a method which draws the object to be animated, we can repeatedly call that method from a loop (within paint()), each time changing one or more of the parameters slightly, giving the illusion of smooth motion.

For example, if you are drawing Pinocchio (and you plan to later animate him), you should create a method called drawPinocchio(), which will have four parameters: the graphics environment, Pinocchio's X coordinate, Pinocchio's Y coordinate, and the fourth his nose length. To draw Pinocchio in the middle of the screen, with a small nose, you might use the piece of code

drawPinocchio(200,100,10);

To animate Pinocchio with a growing nose, you could do something like

for(int noseLength = 10; noseLength < 50; noseLength++)
{
  drawPinocchio(g2, 200,100, noseLength);
  pause(40);
}

Each time through the loop the variable noseLength is incremented by one, so Pinocchio’s nose get longer and longer.


Your Task


Graphics2D and Related Classes

Here’s a description of some of the graphics methods available to you in Java. Remember to use at least three of them in your program.

As with all methods, these function properly when the information provided them is what they expect–and they often produce compile or run-time errors or produce incorrect output if they get something unexpected. Unfortunately, no complex routine’s description, it seems, is ever perfectly complete or completely correct. You may need to experiment a bit with these methods to be sure how they work. You can also obtain much more information about these and other Graphics2D methods by goping to the Java 2 Standard Edition Documentation Page and clicking on Graphics2D (located in the lower left window).

To have access to these methods, you need to import java.awt.* and java.awt.geom.* into your program.

Below, g2 refers to a Graphics2D object (the current graphics environment).

g2.setColor(color constant)

Sets this graphics context’s current color to the specified color. All subsequent graphics operations using this graphics context use this specified color.

The predefined colors are

Color.black Color.blue Color.cyan
Color.darkGray Color.gray Color.green
Color.lightGray Color.magenta Color.orange
Color.red Color.pink  
Color.white Color.yellow  

It is also possible to specify arbitrary colors by creating a new color object. The syntax is

Color test = new Color(R,G,B);

where R is the amount of red, G the amount of green and B the amount of blue in the new color. The values of R, G and B can vary between 0 and 255 (with 255 meaning full saturation). For example, black is (0,0,0), white is (255,255,255) and a light greenish blue is (0,200,200).

You can use the ability to create arbitrary colors to do special effects. Consider the following section of code:

for (loopCount = 0; loopCount <= 255; loopCount++)
{
  Color Fade = new Color(loopCount,loopCount,0);
  drawPacman(g2, pacmanCoordX, pacmanCoordY, pacmanAngle,fade);
  pause(80);
}

In the first iteration of the loop, the user-defined color is pure black; in every subsequent iteration, the color is changed to one slightly more yellow. The effect is one of Pacman slowly fading into view.

Here’s an example of using your own color:

Color myEyeColor = new Color(0,255,240);    // Define color of my eyes
g2.setColor(MyEyeColor);    // Make new color default color
Ellipse2D.Double oval = new Ellipse2D.Double(200,100, 30,30);   // Build the iris (in the new color)
g2.draw(oval);   // Draw it
g2.setColor(Color.black);    // Make Black the default color
oval.setFrame(200,100, 10,10);    // Change the oval to be the pupil
g2.draw(oval);   // Draw it (in black)

Trying to find the exact color you want can be frustrating, involving lots of trial and error. We recommend that you use the predefined colors wherever possible.

g2.draw(shape)

Draws the passed shape, such as an arc, rectangle, rounded rectangle, line or ellipse, in the current color.

g2.fill(shape)

Draws the passed shape, such as an arc, rectangle, rounded rectangle, line or ellipse.

Arc2D.Double(x, y, width, height, startAngle, arcAngle, TYPE)

Constructs a single circular or elliptical arc. The center of the arc is the center of the rectangle whose origin is at the given x and y coordinates and whose size is specified by the width and height arguments.

The two axes of the arc are given by the width and height arguments. The arc is drawn from startAngle to startAngle + arcAngle. The start angle and arc angles are in degrees, not radians. A start angle of 0 indicates the 3-o’clock position. A positive arc angle indicates a counter-clockwise rotation; a negative arc angle indicates a clockwise rotation. TYPE choices are Arc2D.OPEN, which just draw the line, Arc2D.CHORD, which joins the ends of the arc with a straight line, and Arc2D.PIE, which makes a pie-shaped wedge from the arc.

arcObject.setArc(X coordinate, Y coordinate, width, height, startAngle, arcAngle, TYPE)

Redefines the shape of an existing arc. The method’s parameters are the same as Arc2D.Double(). It does not return a value (the return type is void).

Line2D.Double(x1 , y1, x2, y2)

Constructs a line from (x1,y1) to (x2,y2).

lineObject.setLine(x1 , y1, x2, y2)

Redefines the shape of an existing line. The method’s parameters are the same as Line2D.Double(). It does not return a value.

g2.drawPolygon(xPoints[], yPoints[], nPoints)

Draws a closed polygon defined by an array of x points and y points. This method draws the polygon defined by npoint line segments, where the first npoint-1 line segments are lines segments from xPoints[i] to yPoints[i]. The last line segment starts at the final point and ends at the first point.

fillPolygon

 

Same as drawPolygon() except it fills the polygon in the current color.

Rectangle2D.Double( x, y, width, height)

Constructs a rectangle. The left and right edges of the rectangle are at x and x + width respectively. The top and bottom edges of the rectangle are at y and y + height respectively.

rectangle2DObject.setRect( x, y, width, height)

Redefines the shape of an existing rectangle. The method’s parameters are the same as Rectangle2D.Double(). It does not return a value).

RoundRectangle2D.Double( x, y, width, height, arcWidth, arcHeight)

Constructs a rectangle with rounded corners. The first four parameters are the same as Rectangle2D.Double(). arcWidth is the width, and arcHeight is the height, of the arc (in pixels) that rounds off the corners.

rectangle2DObject.setRoundRect( x, y, width, height, arcWidth)

Redefines the shape of an existing rounded rectangle. The method’s parameters are the same as RoundRectangle2D.Double(). It does not return a value.

g2.draw3DRect( x, y, width, height, raised)

Draws a highlighted 3-D rectangle. The first four parameters are the same as RoundRectangle2D.Double(). raised is a boolean that, if true, causes the rectangle appears raised and if false, causes it appears lowered.

g2.fill3DRect

fill3DRect(int x, int y, int width, int height, boolean raised)

Same as draw3DRect() except it fills the Rectangle in the current color.

g2.drawString(str, x, y)

Draws the String str using this graphics context’s current font and color. The baseline of the first character is at position (x,y).

  Written by Norman Jacobson, Winter 1995. Based on an idea from David G. Kay; uses some text from the Fall 1994 version of “Using THINK Pascal,” an ICS21 lab assignment
  Rewritten to use Java and Windows NT by Eamonn Keogh and Norman Jacobson, Sept. 1997
  Minor revisions by Norman Jacobson, April 1998, August 1999
  Revised for presentation on the Web and to use the Graphics2D class by Norman Jacobson, September 2002
  Revised to reflect browsers that recognize Graphics2D methods, by Norman Jacobson, September 2003