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

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