350 likes | 424 Views
Class 13 - Animation. Summary of loops while-do for do-while while loop examples for loop examples for loops in applets. Review: Iteration. Three different forms of iteration while do-while for. While loops. contains variables that are changed in loop. while ( condition )
E N D
Class 13 - Animation • Summary of loops • while-do • for • do-while • while loop examples • for loop examples • for loops in applets
Review: Iteration • Three different forms of iteration • while • do-while • for
While loops contains variables that are changed in loop while (condition) statement repeat until condition becomes true Keep in mind that statement can be a compound statement.
For loops init; while (cond) { S incr; } for (init; cond; incr) S
Do-while loops S; while (cond) S do S while (cond)
Loops are recursive statements If (cond){ S while (cond) S } while (cond) S
for loops • Convenient syntax for loops with loop variables that are incremented or decremented each time through the loop (as in previous examples). • Recall: init; while (cond) { S incr; } for (init; cond; incr) S
for loop examples Sum integers: s = 0; x = 5; while (x > 0) { s = s+x; x = x-1; } s = 0; for (x = 5; x > 0; x = x-1) s = s+x;
for loop examples s = 0; x = 1; while (x <= 10) { s = s+x; x = x+1; } s = 0; for (x = 1; x <= 10; x = x+1) s = s+x;
for loop usage One use of for loops is simply to execute a statement, or sequence of statements, a fixed number of times: for (i = 1; i <= n; i = i+1) S executes S exactly n times.
Animation • Continuous change in displayed graphics. • Effect obtained by repainting scenes repeatedly.
Example: RollingEyesApplet This applet shows a pair of eyes with pupils, which roll when a button is pushed. Here, the loop is in the paint method. We structure this applet into three classes: • RollingEyesApplet: Construct a RollingEyes object. In the paint method, in a loop ranging from 0 to 360, call the draw method on that object.
Example: RollingEyesApplet (cont.) • RollingEyes: A pair of eyes next to each other. Its draw method calls the draw method on each eye. • RollingEye: An eye with a pupil. The draw method has an angle argument and draws the pupil at that angle.
Example: RollingEyesApplet (cont.) public class RollingEyesApplet extends Applet implements ActionListener { Button roll = new Button("Roll 'em"); RollingEyes pair1; public void init () { pair1 = new RollingEyes(200,100); add(roll); roll.addActionListener(this); } public void actionPerformed (ActionEvent e) { repaint(); }
Example: RollingEyesApplet (cont.) public void paint(Graphics g) { int i; for (i=0; i<360; i = i+1) pair1.draw(g, 2*Math.PI*i/360.0); } }
Example: RollingEyesApplet (cont.) public class RollingEyes { RollingEye eye1, eye2; int x, y; final int EYE_RADIUS = 40, PUPIL_RADIUS = 10; RollingEyes (int x, int y) { eye1 = new RollingEye(x-EYE_RADIUS, y, EYE_RADIUS); eye2 = new RollingEye(x+EYE_RADIUS, y, EYE_RADIUS); }
Example: RollingEyesApplet (cont.) void draw (Graphics g, double theta) { eye1.draw(g, theta); eye2.draw(g, theta); } }
Example: RollingEyesApplet (cont.) public class RollingEye { int x, y; int eye_rad, pupil_rad; int distToPupil; RollingEye (int x, int y, int rad) { this.x = x; this.y = y; eye_rad = rad; pupil_rad = rad/4; distToPupil = eye_rad - pupil_rad; }
Example: RollingEyesApplet (cont.) void draw (Graphics g, double theta) { // draw eye with pupil at angle theta int x0 = (int)(distToPupil * Math.cos(theta)), y0 = (int)(distToPupil * Math.sin(theta)); fillCircle(g, x, y, eye_rad, Color.pink); fillCircle(g, x+x0, y+y0, pupil_rad, Color.black); } void fillCircle(Graphics g, int x, int y, int rad, Color c) { g.setColor(c); g.fillOval(x-rad, y-rad, 2*rad, 2*rad); } }
Example: Slower rolling eyes Speed of rolling eyes depends on speed of the computer. Often, such loops go so fast that they can’t easily be seen. To slow down the rolling, change the paint method to:
Example: Slower rolling eyes (cont.) • public void paint(Graphics g) { • int i; • for (i=0; i<360; i = i+1) { • pair1.draw(g, 2*Math.PI*i/360.0); • try { • Thread.sleep(10); • } catch (InterruptedException t) {} • } • } The highlighted portion creates a pause in the middle of a computation, here adding a 10 millisecond delay to each iteration of the loop.
The RollingEyes applet (cont.) • Previously saw how to put loop in paint method, and how to slow it down. • Next problem: how to reduce flicker. • Flicker caused by constant redrawing of entire applet window. • Better solution: Leave eyes alone, just redraw pupils.
The RollingEyes applet (cont.) • Idea: separate eye-drawing method from pupil-drawing method. Call eye-drawing method before loop, pupil-drawing method within loop. (Eye drawing is another example of a loop-invariant computation.) • Need changes in RollingEyes and RollingEye classes. Main change is in loop in paint method:
The RollingEyes applet (cont.) The applet stays the same except for the new version of paint: public void paint(Graphics g) { int i; pair1.drawEyes(g); for (i=0; i<360; i = i+1) pair1.drawPupils(g, 2*Math.PI*i/360.0); }
The RollingEyes applet (cont.) The RollingEyes class has the new methods drawEyes and drawPupils. void drawEyes (Graphics g) { eye1.drawEye(g); eye2.drawEye(g); } void drawPupils (Graphics g, double theta) { eye1.drawPupil(g, theta); eye2.drawPupil(g, theta); }
The RollingEyes applet (cont.) The RollingEye class has the new methods drawEyes and drawPupils, also. void drawEye (Graphics g) { fillCircle(g, x, y, eye_rad, Color.pink); } void drawPupil (Graphics g, double theta) { // draw eye with pupil at angle theta int x0 = (int)(distToPupil * Math.cos(theta)), y0 = (int)(distToPupil * Math.sin(theta)); fillCircle(g, x+x0, y+y0, pupil_rad, Color.black); }
Window not cleared • However, this doesn’t work. Here is a screen dump after rolling eyes once:
Window not cleared (cont.) • Problem: Window not cleared each time drawPupil is called on eyes. • Can get window cleared in various ways, but that would not solve problem: if we clear the window each time we draw pupils in a different location, we would have to redraw the eyes as well as the pupils, which is just what we’re trying to avoid.
“Draw incremental changes only” • Right way to do this is to draw what changes at each step. In this case, it means erasing the previous pupil and drawing the new one. • Add new method on RollingEye: redrawPupils. Arguments are Graphics object, angle, and previous angle.
Final version of RollingEyesApplet Change paint method in applet: public void paint(Graphics g) { int i; double one_degree = 2*Math.PI/360.0; pair1.drawEyes(g); pair1.drawPupils(g, 0.0); for (i=1; i<360; i = i+1) pair1.reDrawPupils(g, i*one_degree, (i-1)*one_degree); }
Final version of RollingEyesApplet (cont.) RollingEyes just calls corresponding methods in Rolling Eye: void drawPupils (Graphics g, double theta) { eye1.drawPupil(g, theta); eye2.drawPupil(g, theta); } void reDrawPupils (Graphics g, double theta, double thetaprev) { eye1.reDrawPupil(g, theta, thetaprev); eye2.reDrawPupil(g, theta, thetaprev); }
Final version of RollingEyesApplet (cont.) In RollingEye, drawPupils is unchanged, but redrawPupils erases old pupil first: void reDrawPupil (Graphics g, double theta, double thetaprev) { // erase previous pupil int x0 = (int)(distToPupil * Math.cos(thetaprev)), y0 = (int)(distToPupil * Math.sin(thetaprev)); fillCircle(g, x+x0, y+y0, pupil_rad, Color.pink); // and draw new pupil x0 = (int)(distToPupil * Math.cos(theta)); y0 = (int)(distToPupil * Math.sin(theta)); fillCircle(g, x+x0, y+y0, pupil_rad, Color.black); }
Aside: Rolling forever • Can have applet that simply rolls eyes forever. However, can’t do it like this:because it would tie up the browser. • Instead, need to relinquish control to the browser occasionally. public void paint(Graphics g) { int i; for (i=0; i<360; i = (i+1)%360) pair1.draw(g, 2*Math.PI*i/360.0); }
Aside: Rolling forever (cont.) • To relinquish control, call repaint(). repaint does not simply call paint, but deos something more complicated: It goes back to the browser, and tells it to schedule a call to paint at some later time (whenever the browser has nothing better to do). This gives the browser the opportunity to do other, more pressing work.
Aside: Rolling forever (cont.) The new version of RollingEyesApplet: public class RollingEyesApplet6 extends Applet { RollingEyes5 pair1; int lastangle = 0; public void init () { pair1 = new RollingEyes5(200,100); } public void paint(Graphics g) { pair1.draw(g, 2*Math.PI*lastangle/360.0); lastangle = (lastangle+1) % 360; repaint(); } }