//Animation Applet, version 2 Last updated 2/21/99 //M.Dubson, Feb. 1999, ENVD 3252 import java.awt.*; import java.applet.Applet; import java.awt.event.*; import java.lang.Thread; public class Animation2Balls extends Applet implements Runnable, MouseListener, MouseMotionListener { Thread theThread; Image offscreen; double w,h; //width and height of screen, will need to do floating-point arithmatic double a; //acceleration of gravity //int x1, y1, x2, y2; //int vx1, vy1, vx2, vy2; double x1, y1, x2, y2; //present positions double x1_Last, y1_Last, x2_Last, y2_Last; //previous positions double vx1, vy1, vx2, vy2; //present velocities double vx1_Last, vy1_Last, vx2_Last, vy2_Last; //previous velocities double dt; //time step double dR; // distance between ball centers double dV; // magnitude of velocity difference double dRx, dRy, dVx, dVy; // x- and y-components of position difference and //velocity difference vectors double r1; //radius of ball double d1; //diameter of ball public void init() { addMouseMotionListener(this); addMouseListener(this); w = (double) getSize().width; h = (double) getSize().height; a = 0.3; r1 = w/15.0; d1 = 2*r1; dt = 0.2; x1 = 2*r1; y1 = 3*r1; x2 = w - 2*r1; y2 = 3*r1; vx1 = 15; vy1 =0; vx2 = -4; vy2 = 0.5; dR = Math.sqrt(Math.pow((x2-x1),2)+Math.pow((y2-y1),2)); //dV = Math.sqrt(Math.pow((vx2-vx1),2)+Math.pow((vy2-vy1),2)); } public void step() { Graphics g = getGraphics(); dR = Math.sqrt(Math.pow((x2-x1),2)+Math.pow((y2-y1),2)); //distance between balls if (dR < d1) //if balls collide { x1 -= vx1*dt; //if collision has occured, back up a step y1 -= vy1*dt; x2 -= vx2*dt; y2 -= vy2*dt; dR = Math.sqrt(Math.pow((x2-x1),2)+Math.pow((y2-y1),2)); //recompute distance double b = (x2-x1)*(vx2-vx1)+(y2-y1)*(vy2-vy1); double dvx = b*(x2-x1)/Math.pow(dR,2); double dvy = b*(y2-y1)/Math.pow(dR,2); vx1 += dvx; vy1 += dvy; vx2 += -dvx; vy2 += -dvy; System.out.println("Collision has occurred."); } if ((x1 > w-r1 && vx1 > 0) || (x1 < r1 && vx1 < 0) ) { vx1 *= -1; } if ((y1 > h-r1 && vy1 > 0) || (y1 < r1 && vy1 < 0)) { vy1 *= -1; } if ((x2 > w-r1 && vx2 > 0) || (x2 < r1 && vx2 < 0)) { vx2 *= -1; } if ((y2 > h-r1 && vy2 > 0) || (y2 < r1 && vy2 <0)) { vy2 *= -1; } vy1 += a*dt; vy2 += a*dt; x1 += vx1*dt; y1 += vy1*dt; x2 += vx2*dt; y2 += vy2*dt; repaint(); }//End of step method public void paint(Graphics g) { g.setColor(Color.yellow); g.fillRect(0,0,(int)w,(int)h); g.setColor(Color.red); g.fillOval( (int)(x1 - r1), (int)(y1 - r1), (int)(2*r1),(int) (2*r1)); g.setColor(Color.blue); g.fillOval( (int)(x2 - r1), (int)(y2 - r1), (int)(2*r1), (int)(2*r1)); }//end of paint method public void update( Graphics g ) { if (offscreen == null || offscreen.getHeight(this) != h || offscreen.getWidth(this) != w) { offscreen = createImage((int)w, (int)h);} Graphics g2 = offscreen.getGraphics(); paint(g2); g.drawImage( offscreen, 0, 0, this); }// end of update method public void start() { if( theThread == null ){theThread = new Thread( this );} theThread.start(); } public void run() { while( true ) { step(); try { theThread.sleep( 10 ); } catch( Exception e ) {;} } }//end of run method public void stop() { if( theThread != null && theThread.isAlive() ) { theThread.stop(); } theThread = null; } public void mousePressed( MouseEvent e) {;} public void mouseDragged( MouseEvent e) {;} public void mouseReleased( MouseEvent e) {;} public void mouseMoved( MouseEvent e) {;} public void mouseClicked( MouseEvent e) {;} public void mouseEntered( MouseEvent e) {;} public void mouseExited( MouseEvent e) {;} } // End of class Animation