import java.awt.*; import java.applet.*; import java.util.Vector; //************************************************************************************* //********************** Our Canvas ************************************************ //************************************************************************************* class our_canvas extends Canvas { public void update(Graphics g) { } public void paint(Graphics g) { } } //************************************************************************************* //************************************************************************************* //*************************** Ball Class ********************************************* //************************************************************************************* //************************************************************************************* class Ball { static int box_width; static int box_height; //Following properties are set in the constructor int initial_x; int initial_y; int initial_xdelta; int initial_ydelta; int ball_width; int radius; Image ball_pic; //Dynamic properties int center_x; //The current position of the center of the ball int center_y; int pos_x; //The current position of the upper left corner of the picture int pos_y; int delta_x; //The delta value of the ball(speed and direction) int delta_y; //Constructor Ball(int initial_x_in, int initial_y_in, int initial_xdelta_in, int initial_ydelta_in, int ball_width_in, Image ball_pic_in) { initial_x = initial_x_in; initial_y = initial_y_in; delta_x = initial_xdelta_in; delta_y = initial_ydelta_in; ball_width = ball_width_in; ball_pic = ball_pic_in; radius = ball_width / 2; center_x = initial_x + radius; center_y = initial_y + radius; pos_x = initial_x; pos_y = initial_y; } public void move_ball() { pos_x += delta_x; pos_y += delta_y; if ( (pos_x > (box_width - ball_width) ) || (pos_x < 0) ) { flip_horz_direction(); } if ( (pos_y > (box_height - ball_width) ) || (pos_y < 0) ) { flip_vert_direction(); } center_x = pos_x + radius; center_y = pos_y + radius; } public void flip_horz_direction() { delta_x *= -1; pos_x += delta_x; center_x = pos_x + radius; } public void flip_vert_direction() { delta_y *= -1; pos_y += delta_y; center_y = pos_y + radius; } public void set_delta(int delta_x_in, int delta_y_in) { delta_x = delta_x_in; delta_y = delta_y_in; } } //************************************************************************************* //************************************************************************************* //************************************************************************************* //************************************************************************************* //************************************************************************************* //*************************** The Applet ********************************************* //************************************************************************************* //************************************************************************************* public class bouncing_balls extends Applet implements Runnable { private AudioClip boink_sound; private Button add_button, subtract_button; MediaTracker mt; Image ball_img = null; Image background_img; int ball_width; int b_width; int b_height; Image img_buffer; Graphics g_buffer; Graphics g_canvas; Vector ball_vector; private Thread animate; our_canvas ball_canvas; //************************ Start ************************************* public void start() { super.init(); boink_sound = getAudioClip( getDocumentBase(), "boink.au"); ball_vector = new Vector (1); ball_img = getPicImage("ball.gif"); ball_width = ball_img.getWidth(null); background_img = getPicImage("sky.gif"); b_width = background_img.getWidth(null); b_height = background_img.getHeight(null); this.resize(b_width, b_height + 35 ); //Leave room for the buttons img_buffer = createImage( b_width, b_height); g_buffer = img_buffer.getGraphics(); Ball.box_width = b_width; Ball.box_height = b_height; ball_canvas = new our_canvas(); ball_canvas.resize(b_width, b_height); add(ball_canvas); add_button = new Button("Add Ball"); subtract_button = new Button("Subtract Ball"); add(add_button); add(subtract_button); add_ball(); //Start with one ball if (animate == null) { animate = new Thread (this); animate.start(); } } //******* Run- this method is called by the thread "animate" and starts an endless loop *** public void run() { try { for (;;) { Thread.sleep(15); //We repaint the screen every 15 micro seconds collision_detect(); move_balls(); repaint(); } } catch(InterruptedException e) { return; }; } //************************ Stop ************************************* public void stop() { if (animate != null) { animate.stop(); animate=null; } } //************************ Action ************************************* public boolean action(Event evt, Object what) { if (evt.target == add_button) { add_ball(); } if (evt.target == subtract_button) { subtract_ball(); } return true; } //************************ Update ************************************* public void update(Graphics g) { paint(g); } //************************ Paint ************************************* public void paint(Graphics g) { g_buffer.drawImage(background_img, 0, 0, null); for ( int i=0; i < ball_vector.size(); i++) { Ball hold_ball = (Ball) ball_vector.elementAt(i); g_buffer.drawImage( hold_ball.ball_pic, hold_ball.pos_x, hold_ball.pos_y, null); } g_canvas= ball_canvas.getGraphics(); g_canvas.drawImage(img_buffer, 0, 0, null); } //*************** Add a bouncing ball to the Applet ****************** public void add_ball() { int initial_x = (int) ( Math.random() * (b_width - ball_width) ); int initial_y = (int) ( Math.random() * (b_height - ball_width) ); int intial_delta_x = (int) (Math.random() * 2) + 1; int intial_delta_y = (int) (Math.random() * 2) + 1; ball_vector.addElement( new Ball( initial_x, initial_y, intial_delta_x, intial_delta_y, ball_width, ball_img) ); } //*************** Subtract a bouncing ball from the Applet ****************** public void subtract_ball() { if ( ball_vector.size() > 0 ) ball_vector.removeElementAt(0); } //*************** Move the balls ******************************************** public void move_balls() { for ( int i=0; i < ball_vector.size(); i++) { ((Ball)ball_vector.elementAt(i)).move_ball(); } } //********************* Collsion detection ******************** public void collision_detect() { int A, B; double C; int curr_ball; int hold_delta_x; int hold_delta_y; for ( curr_ball = 0; curr_ball < ball_vector.size(); curr_ball++) { for ( int i=0; i < ball_vector.size(); i++) { if ( i != curr_ball) { Ball hold_curr_ball = (Ball)ball_vector.elementAt(curr_ball); Ball hold_check_ball = (Ball)ball_vector.elementAt(i); A = Math.abs(hold_curr_ball.center_x - hold_check_ball.center_x); B = Math.abs(hold_curr_ball.center_y - hold_check_ball.center_y); C = Math.sqrt( (A*A) + (B*B) ); if (C < ( hold_curr_ball.radius + hold_check_ball.radius) ) { boink_sound.play(); hold_delta_x = hold_curr_ball.delta_x; hold_delta_y = hold_curr_ball.delta_y; hold_curr_ball.set_delta(hold_check_ball.delta_x, hold_check_ball.delta_y); hold_check_ball.set_delta(hold_delta_x, hold_delta_y); hold_curr_ball.move_ball(); hold_check_ball.move_ball(); } } } } } //*************** getPicImage ************************************** // Use MediaTracker to insure the images are fully loaded before // we try to use them private Image getPicImage(String image_file_name) { Image img_work = null; mt = new MediaTracker(this); try { img_work = getImage(getDocumentBase(),image_file_name); } catch(Exception e1) { System.out.println(e1); } mt.addImage(img_work, 0); try { showStatus("Loading image " + image_file_name ); mt.checkID(0, true); mt.waitForID(0); } catch(InterruptedException e2) { System.out.println(e2); } return img_work; } } //---- End of Applet