home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / javafile / ch09 / Bounce.java < prev    next >
Encoding:
Java Source  |  1998-12-14  |  4.7 KB  |  245 lines

  1. import java.awt.*;
  2. import java.awt.event.*;
  3. import java.applet.*;
  4. import java.awt.image.ImageObserver;
  5.  
  6. /*
  7.  * a class describing a single ball
  8.  */
  9. class Ball {
  10.  
  11. /*
  12.  * the image for this ball
  13.  */
  14. Image img;
  15.  
  16. /*
  17.  * x position and velocity
  18.  */
  19. double x, dx;    // x position and velocity
  20.  
  21. /*
  22.  * y position and velocity
  23.  */
  24. double y, dy;    // y position and velocity
  25.  
  26. /*
  27.  * initialize the position and velocity
  28.  * to random values
  29.  */
  30. void random () {
  31.     x = 10 + 380*Math.random ();
  32.     y = 10 + 200*Math.random ();
  33.     dx = 5 - 10*Math.random ();
  34.     dy = 5 - 10*Math.random ();
  35. }
  36.  
  37. /**
  38.  * calculate the next position of this ball
  39.  * and make sure it bounces off the edge of the panel
  40.  * @param d - dimension of the bounding panel
  41.  */
  42. void compute (Dimension d) {
  43.     if (x <= 0 || x > d.width) dx = -dx;    // bounce horizontal
  44.     if (y <= 0 || y > d.height) dy = -dy;    // bounce vertical
  45.     x += dx;
  46.     y += dy;
  47. }
  48.  
  49. /**
  50.  * draw the ball image
  51.  * @param g - destination graphics object
  52.  * @param obs - parent image observer
  53.  */
  54. public void paint (Graphics g, ImageObserver obs) {
  55.  
  56.     g.drawImage (img, (int) x-10, (int) y-10, obs);
  57. }
  58. }
  59.  
  60. /*
  61.  * the panel containing the bouncing balls
  62.  */
  63. class BouncePanel extends Panel implements Runnable {
  64.  
  65. /*
  66.  * the number of balls
  67.  */
  68. final int nballs = 4;
  69.  
  70. /*
  71.  * the array holding all the balls
  72.  */
  73. Ball balls[] = new Ball[10];
  74.  
  75. /*
  76.  * offscreen image
  77.  */
  78. Image offimg;
  79.  
  80. /*
  81.  * size of offscreen image
  82.  */
  83. Dimension offsize; 
  84.  
  85. /*
  86.  * graphics object associated with offscreen image
  87.  */
  88. Graphics offg;
  89.  
  90. /*
  91.  * thread for periodic updating
  92.  */
  93. Thread thread;
  94.  
  95. /*
  96.  * The thread recalculates each ball position and
  97.  * redraws them
  98.  */
  99. public void run() {
  100.  
  101.     offsize = getSize();
  102.     offimg = createImage (offsize.width, offsize.height);
  103.     offg = offimg.getGraphics();
  104.     while (true) {
  105.         for (int i=0; i<nballs; i+=1) {
  106.             balls[i].compute (offsize); 
  107.         }
  108.         repaint ();
  109.         try {
  110.             Thread.sleep (25);
  111.         } catch (InterruptedException e) {
  112.             break;
  113.         }
  114.     }
  115. }
  116.  
  117. /**
  118.  * Override update to avoid erase flicker
  119.  * @param g - destination graphics object
  120.  */
  121. public synchronized void update (Graphics g) {
  122.  
  123.     offg.setColor (Color.lightGray);
  124.     offg.fillRect (0, 0, offsize.width, offsize.height);
  125.  
  126.     for (int i = 0 ; i < nballs ; i++)
  127.         balls[i].paint (offg, this);
  128.     offg.setColor (Color.black);
  129.     offg.drawRect (0, 0, offsize.width-1, offsize.height-1);
  130.     g.drawImage(offimg, 0, 0, this);
  131. }
  132.  
  133. /*
  134.  * Start the update thread
  135.  */
  136. public void start() {
  137.  
  138.     thread = new Thread(this);
  139.     thread.start();
  140. }
  141.  
  142. /*
  143.  * Stop the update thread
  144.  */
  145. public void stop()
  146. {
  147.  
  148.    if (thread != null)
  149.      thread = null;
  150. }
  151.  
  152. }
  153.  
  154. /*
  155.  * the applet proper
  156.  */
  157. public class Bounce extends Applet implements ActionListener
  158. {
  159.  
  160. /*
  161.  * instance of BouncePanel
  162.  */
  163. BouncePanel panel;
  164.  
  165. /*
  166.  * an array containing the images for the balls
  167.  */
  168. Image img[] = new Image[4];
  169.  
  170. /*
  171.  * the audio clip to be played in a loop
  172.  */
  173. AudioClip sound;
  174. Button btnStart;
  175. Button btnStop;
  176. /*
  177.  * Called when the applet is loaded
  178.  * Create an instance of bounce panel and add the start button
  179.  * and load images
  180.  */
  181. public void init() {
  182.  
  183.     setLayout(new BorderLayout());
  184.  
  185.     panel = new BouncePanel ();
  186.     add ("Center", panel);
  187.     Panel p = new Panel ();
  188.     add ("South", p);
  189.     btnStart = new Button("Start");
  190.     p.add (btnStart);
  191.     btnStop = new Button("Stop");
  192.     p.add (btnStop);
  193.     btnStart.addActionListener(this);
  194.     btnStop.addActionListener(this);
  195.  
  196.     sound = getAudioClip(getCodeBase(),  "sound.au");
  197.  
  198.     img[0] = getImage (getDocumentBase(), "whiteball.gif");
  199.     img[1] = getImage (getDocumentBase(), "redball.gif");
  200.     img[2] = getImage (getDocumentBase(), "blueball.gif");
  201.     img[3] = getImage (getDocumentBase(), "greenball.gif");
  202.     for (int i=0; i<panel.nballs; i+=1) {
  203.         panel.balls[i] = new Ball ();
  204.         panel.balls[i].img = img[i & 3];
  205.     }
  206. }
  207.  
  208. /*
  209.  * Called when the applet is started
  210.  * Don't do anything
  211.  */
  212. public void start () {
  213.  
  214. }
  215.  
  216. /*
  217.  * Called when the applet is stopped
  218.  */
  219. public void stop() {
  220.  
  221.     panel.stop();
  222.     sound.stop ();
  223. }
  224.  
  225. /*
  226.  * Handle start button press by randomizing balls
  227.  */
  228. public void actionPerformed(ActionEvent ev)
  229. {
  230.     Object object1 = ev.getSource();
  231.     if (object1 == btnStart)
  232.     {
  233.         for (int i=0; i<panel.nballs; i+=1)
  234.             panel.balls[i].random ();
  235.         panel.start ();
  236.         sound.loop ();
  237.     }
  238.     if (object1 == btnStop)
  239.     {
  240.         sound.stop ();
  241.     }
  242. }
  243.  
  244. }
  245.