001: //File: FishWinks.java
002: //Uses: DrawingObjectList.java
003: //Uses: FlipBook.java
004: 
005: /* This is a simple object-list and flip-book based
006:    drawing of a fish swimming across the screen and
007:    and winking when his/her eye is at the middle
008:    of the screen.
009: 
010:    Note that the fish is to swim from the right to
011:    the left.
012: 
013:    H. J. Bernstein, 29 November 2003
014:    
015:  */
016: 
017: 
018: import java.awt.*;
019: import java.awt.event.*;
020: import java.awt.image.*;
021: import java.applet.Applet;
022: 
023: public class FishWinks extends Applet
024: {
025: // Global data
026:     DrawingObjectList dol = null;
027: 
028: // Initialization
029:   public void init() {
030:     dol = null;
031:   }
032: 
033: 
034: // paint method to to the actual drawing
035:   public void paint (Graphics g_real) {
036:     
037:     // declare variables
038:     Graphics g;       // a graphics object
039:     Dimension size    // dimensions of the window
040:         = getSize();
041:     int frame;        // the current frame
042:     int frames;       // the total number of frames
043:     int cx = size.width,
044:         cy = size.height,
045:         diameter = (int)(.2*Math.min(cx, cy));
046:     int ii;
047:     int shift;
048:     int rshift;
049:     Color bodycolor = Color.yellow;             // yellow body
050:     Color seacolor  = new Color(128,128,255);   // light blue sea
051:     Color linecolor = Color.red;                // red line color
052:      
053:     frames = (int)(cx+diameter*4.0);
054:     
055:     // If the DOL exists and is the right size
056:     // use the pages we already created.
057:     
058:     if (dol == null 
059:        || dol.curFrames != frames 
060:        || dol.curWidth != cx 
061:        || dol.curHeight != cy ) {
062:        
063:       dol = new DrawingObjectList(g_real,cx,cy, this, frames);
064: 
065:       // draw some waves
066:       dol.setColor(seacolor,0,frames-1);
067:       // first fill the background with blue to the tops of the wave2
068:       dol.fillRect(0,diameter/2,cx-1,cy-1-diameter/2,0,frames-1);
069:       // now change to white and cut out the waves
070:       dol.setColor(Color.white,0,frames-1);
071:       for(ii=0; ii< cx; ii += diameter) {
072:         dol.fillOval(ii,diameter/6,diameter,diameter/2,0,frames-1);
073:       }
074:     
075:       for (frame = 0; frame < frames; frame++) {
076:         int ledge;                       // front of the fish
077:         ledge  = frames-frame-2*diameter-diameter/2;
078:         dol.setFrame(frame);
079: 
080:         // we now need to draw our fish.  We will use two
081:         // filled arcs for the body, of length 2*diameter and
082:         // height diameter.  To come in from the right
083:         // we shift in x by frames-3*frame
084: 
085:         // We will need a periodic shift
086:  
087:         shift = (frame%42) -10;          // a number from -10 through 31
088:         if (shift > 10 ) shift = 21-shift;// now -10 through 10
089:                                           // and 10 down to -10
090:         rshift = (diameter*shift)/10;     // and -diameter through diameter
091: 
092: 
093:         // Draw a dorsal fin
094: 
095:         dol.setColor(bodycolor);
096:         dol.fillArc(ledge+diameter+diameter/4-diameter/3,cy/2-2*diameter/3,
097:         2*diameter/3,diameter/3,90,180);
098:         dol.setColor(seacolor);
099:         dol.fillOval(ledge+diameter+diameter/4-diameter/6,cy/2-2*diameter/3,
100:         diameter/3,diameter/3);
101: 
102:         // Draw the body with the mouth working
103: 
104:         dol.setColor(bodycolor);
105:         dol.fillArc(ledge,cy/2-diameter/2,
106:         2*diameter,diameter,0,170+shift);
107:         dol.fillArc(ledge,cy/2-diameter/2,
108:         2*diameter,diameter,190-shift,170+shift);
109:         
110:         // Add a tail, make it waggle
111: 
112:         dol.fillArc(ledge+2*diameter,cy/2-diameter/4,
113:         diameter,diameter/2,90,180);
114:         dol.setColor(seacolor);
115:         dol.fillArc(ledge+2*diameter+diameter/4-rshift/6+1,
116:         cy/2-diameter/4,
117:         diameter/2+rshift/3,diameter/2,90,180);
118: 
119:         // draw side fin
120: 
121:         dol.setColor(linecolor);
122:         dol.drawArc(ledge+diameter+diameter/10,
123:           cy/2-diameter/4+(rshift+diameter)/8,
124:           2*diameter/3,diameter/2-(rshift+diameter)/4,180,90);
125:         dol.drawArc(ledge+diameter+diameter/10+diameter/6,
126:           cy/2-diameter/4+(rshift+diameter)/8,
127:           diameter/3,diameter/2-(rshift+diameter)/4,180,90);
128: 
129:         // draw an eye
130: 
131:         dol.drawOval(ledge+diameter-diameter/2-diameter/10,
132:            cy/2-diameter/4-diameter/10,
133:            diameter/5,diameter/5);
134:         dol.fillOval(ledge+diameter-diameter/2-diameter/20,
135:            cy/2-diameter/4-diameter/20,
136:            diameter/10,diameter/10);
137: 
138:         // blink the eye if we are near the middle
139: 
140:         if ((ledge+diameter-diameter/2 - cx/2) > -diameter/5 &&
141:             (ledge+diameter-diameter/2 - cx/2) < diameter/5 ) {
142:            dol.setColor(bodycolor);
143:            // half close the eye
144:            dol.fillArc(ledge+diameter-diameter/2-diameter/10-1,
145:            cy/2-diameter/4-diameter/10-1,
146:            diameter/5+2,diameter/5+2,0,180);
147:            // close completely in the middle
148:            if ((ledge+diameter-diameter/2 - cx/2) > -diameter/10 &&
149:              (ledge+diameter-diameter/2 - cx/2) < diameter/10 ) {
150:              dol.setColor(bodycolor);
151:              dol.fillArc(ledge+diameter-diameter/2-diameter/10-1,
152:              cy/2-diameter/4-diameter/10,
153:              diameter/5+2,diameter/5-1,0,-180);
154:              dol.setColor(linecolor);
155:              dol.drawArc(ledge+diameter-diameter/2-diameter/10-1,
156:              cy/2-diameter/4-diameter/10,
157:              diameter/5+2,diameter/5-1,0,-180);
158:            } else {
159:              dol.setColor(linecolor);
160:              dol.drawLine(ledge+diameter-diameter/2-diameter/10,
161:                cy/2-diameter/4,
162:                ledge+diameter-diameter/2+diameter/10,
163:                cy/2-diameter/4);
164:            }
165:         } 
166:       }
167:     } 
168:     
169:     // display the entire set of frames
170:     for (frame = 0; frame < frames; frame++) {
171: 
172:  
173:       dol.ShowPage(this,frame);
174:       try {
175:         Thread.sleep(25);               // sleep for 25 msec
176:       } catch (InterruptedException t){}
177:     }
178:    try {
179:       Thread.sleep(1000);              // sleep or 1 sec
180:     } catch (InterruptedException t) {}
181:     repaint();
182:   }
183: 
184: }