// mas964 ps4 // base class for animation, uses two mouseclicks and then starts off // an animation, calling drawFrame(time) governed by timings.. // the two mouseclicks stuff should be abstracted from the general // animator, but there are some bugs in the animator, it's dropping // a few milliseconds. import java.applet.*; import java.awt.*; import java.lang.Math; import DoubleBufferApplet; public abstract class TwoPointAnimator extends DoubleBufferApplet implements Runnable { protected int frameDelay, animationLength; protected long startTime; protected Thread animatorThread; protected boolean threadDebugInfo = false; protected int numButtonsPressed = 0; protected int x1, y1, x2, y2; // millisecond timings. Length <= 0 means never stop. // these values are also read from "length" and "delay" properties protected void setTiming(int delay, int length) { frameDelay = delay; animationLength = length; } // this is called with how many milliseconds we are into the animation public abstract void drawFrame(int ms); public boolean mouseDown(Event e, int x, int y) { if (numButtonsPressed == 0) { x1 = x; y1 = y; numButtonsPressed++; } else if (numButtonsPressed == 1) { x2 = x; y2 = y; numButtonsPressed++; stop(); // kill anything running start(); numButtonsPressed = 0; } else { System.out.println("Logic error - too many buttons pressed."); } return true; } public void start() { if (threadDebugInfo) System.out.println("Start was called " + System.currentTimeMillis()); if (frameDelay == 0) // should throw an exception System.out.println("Start was called with a 0 frame delay!"); if (numButtonsPressed == 2) { animatorThread = new Thread(this); animatorThread.start(); } } public void stop() { if (threadDebugInfo) System.out.println("Stop was called " + System.currentTimeMillis()); if (animatorThread != null) { animatorThread.stop(); animatorThread = null; } } public void run() { if (threadDebugInfo) System.out.println("Running." + System.currentTimeMillis()); startTime = System.currentTimeMillis(); while (Thread.currentThread() == animatorThread) { long drawStartTime = System.currentTimeMillis(); drawFrame((int)(drawStartTime - startTime)); if (animationLength > 0 && drawStartTime - startTime >= animationLength) stop(); else { try { // sleep to the next frameDelay'th interval after beginning. int delay = (int)(frameDelay - (System.currentTimeMillis() - drawStartTime)); if (delay < 0) delay = delay % frameDelay + frameDelay; // first postive modulus Thread.sleep(delay); } catch (InterruptedException e) { System.out.println("Sleep interrupted?"); } } } } // read in the frame delay and length parameters. public void init() { String delayString = getParameter("delay"); String lengthString = getParameter("length"); try { if (delayString != null) frameDelay = Integer.parseInt(delayString); } catch (Exception e) {} try { if (lengthString != null) animationLength = Integer.parseInt(lengthString); } catch (Exception e) {} super.init(); } }