home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / Visual Cafe Pro v1.0 / SOURCE.BIN / Firework.java < prev    next >
Encoding:
Java Source  |  1997-06-19  |  11.0 KB  |  383 lines

  1. package symantec.itools.multimedia;
  2.  
  3. import java.awt.Canvas;
  4. import java.awt.Graphics;
  5. import java.awt.Color;
  6. import java.awt.Dimension;
  7. import java.net.URL;
  8. import java.util.Random;
  9. import symantec.itools.lang.OS;
  10.  
  11. //    01/29/97    TWB    Integrated changes from Windows
  12. //    02/02/97    RKM    Fixed bug in unfreezeRockets, where freezing twice would not resume
  13.  
  14. /**
  15.  * Firework component.  Creates an animated fireworks image.
  16.  * @version 1.0, Nov 26, 1996
  17.  * @author  Symantec
  18.  */
  19.  
  20. public class Firework
  21.     extends Canvas
  22.     implements Runnable
  23. {
  24.     /**
  25.      * Speed at which animation occurs.  Delay time = 100 / AnimationSpeed.
  26.      * Default value 10.
  27.      */
  28.     public int AnimationSpeed = 10;
  29.  
  30.     /**
  31.      * Chance of different rocket style. Rocket sytle changes if Math.random() * 100 < RocketStyleVariability.
  32.      * Default Value 10.
  33.      */
  34.     public int RocketStyleVariability = 10;
  35.  
  36.     /**
  37.      * Maximum number of rockets.
  38.      */
  39.     public int MaxRocketNumber = 9;
  40.     /**
  41.      * Controls "energy" of firwork explosion. Default value 850.
  42.      */
  43.     public int MaxRocketExplosionEnergy = 850;
  44.     /**
  45.      * Controls the density of the firework burst. Larger numbers give higher density.
  46.      * Default value 90.
  47.      */
  48.     public int MaxRocketPatchNumber = 90;
  49.     /**
  50.      * Controls the radius of the firework burst. Larger numbers give larger radius.
  51.      * Default value 68.
  52.      */
  53.     public int MaxRocketPatchLength = 68;
  54.  
  55.     /**
  56.      * Controls gravity of the firework simulation.
  57.      * Default value 400.
  58.      */
  59.     public int Gravity = 400;
  60.  
  61.     private Rocket rocket[];
  62.     private boolean rocketsCreated = false;
  63.     private Thread launcher = null;
  64.     private boolean suspend = false;
  65.  
  66.     /**
  67.      * Construct the defalut firework.
  68.      *
  69.      */
  70.  
  71.     public Firework() {
  72.         super();
  73.     }
  74.  
  75.     /**
  76.      * Tells this component that it has been added to a container.
  77.      * This is a standard Java AWT method which gets called by the AWT when
  78.      * this component is added to a container. Typically, it is used to
  79.      * create this component's peer.
  80.      *
  81.      * It has been overridden here to start the launcher thread.
  82.      *
  83.      * @see #removeNotify
  84.      */
  85.     public void addNotify() {
  86.         super.addNotify();
  87.         launcher = new Thread(this);
  88.         launcher.start();
  89.     }
  90.  
  91.     /**
  92.      * Tells this component that it is being removed from a container.
  93.      * This is a standard Java AWT method which gets called by the AWT when
  94.      * this component is removed from a container. Typically, it is used to
  95.      * destroy the peers of this component and all its subcomponents.
  96.      *
  97.      * It has been overridden here to stop the launcher thread.
  98.      *
  99.      * @see #addNotify
  100.      */
  101.     public synchronized void removeNotify() {
  102.         if (launcher != null) {
  103.             launcher.stop();
  104.             launcher = null;
  105.         }
  106.         super.removeNotify();
  107.     }
  108.  
  109.     /**
  110.      * Makes this component visible.
  111.      * This is a standard Java AWT method which gets called to show this
  112.      * component. If this component was invisible due to a previous hide()
  113.      * call it make this component visible again.
  114.      *
  115.      * @see #hide
  116.      */
  117.     public synchronized void show() {
  118.         super.show();
  119.         if (isVisible()) {
  120.             if (launcher != null)
  121.                 launcher.resume();
  122.         }
  123.     }
  124.  
  125.     /**
  126.      * Makes this component invisible.
  127.      * This is a standard Java AWT method which gets called to hide
  128.      * this component. A hidden component cannot be seen by the user nor
  129.      * does it take up space in its container, but it does continue to
  130.      * exist.
  131.      *
  132.      * @see #show
  133.      */
  134.     public synchronized void hide() {
  135.         super.hide();
  136.         if (!isVisible()) {
  137.             if (launcher != null)
  138.                 suspend = true;
  139.         }
  140.     }
  141.  
  142.  
  143.     void createRockets() {
  144.         rocketsCreated = true;
  145.  
  146.         Rocket tempRocket[] = new Rocket[MaxRocketNumber];
  147.  
  148.         Dimension dim = size();
  149.  
  150.         for (int i = 0; i < MaxRocketNumber; i++)
  151.             tempRocket[i] = new Rocket(dim.width, dim.height, Gravity);
  152.  
  153.         rocket = tempRocket;
  154.     }
  155.  
  156.     /**
  157.      * Moves and/or resizes this component.
  158.      * This is a standard Java AWT method which gets called to move and/or
  159.      * resize this component. Components that are in containers with layout
  160.      * managers should not call this method, but rely on the layout manager
  161.      * instead.
  162.      *
  163.      * @param x horizontal position in the parent's coordinate space
  164.      * @param y vertical position in the parent's coordinate space
  165.      * @param width the new width
  166.      * @param height the new height
  167.      */
  168.     public synchronized void reshape(int x, int y, int width, int height) {
  169.         super.reshape(x, y, width, height);
  170.         rocketsCreated = false;
  171.     }
  172.  
  173.     /**
  174.      * Firework thread body.  This method is called by the Java virtual
  175.      * machine is response to the program's call to the start method of
  176.      * this thread.
  177.      */
  178.     public void run() {
  179.         int i,
  180.  
  181.         e = (int)(Math.random() * MaxRocketExplosionEnergy * 3 / 4) +
  182.             MaxRocketExplosionEnergy / 4 + 1,
  183.         p = (int)(Math.random() * MaxRocketPatchNumber * 3 / 4) +
  184.             MaxRocketPatchNumber / 4 + 1,
  185.         l = (int)(Math.random() * MaxRocketPatchLength * 3 / 4) +
  186.             MaxRocketPatchLength / 4 + 1;
  187.  
  188.         long s = (long)(Math.random() * 10000);
  189.         boolean sleep;
  190.         Graphics g = null;
  191.  
  192.         while (true) {
  193.             if (g == null)
  194.                 g = getGraphics();
  195.  
  196.             if (suspend) {
  197.                 suspend = false;
  198.                 launcher.suspend();
  199.             }
  200.  
  201.             if (!rocketsCreated)
  202.                 createRockets();
  203.  
  204.             if (rocketsCreated && g != null) {
  205.                 Dimension dim = size();
  206.                 if (OS.isMacintosh())
  207.                     g.clipRect(0, 0, dim.width, dim.height);
  208.  
  209.                 try {
  210.                     Thread.sleep(100 / AnimationSpeed);
  211.                 } catch(InterruptedException x) {
  212.                 }
  213.  
  214.                 sleep = true;
  215.  
  216.                 for (i = 0; i < MaxRocketNumber; i++)
  217.                     sleep = sleep && rocket[i].sleep;
  218.  
  219.                 if (sleep && Math.random() * 100 < RocketStyleVariability) {
  220.                     e = (int)(Math.random() * MaxRocketExplosionEnergy * 3 / 4) +
  221.                         MaxRocketExplosionEnergy / 4 + 1;
  222.                     p = (int)(Math.random() * MaxRocketPatchNumber * 3 / 4) +
  223.                         MaxRocketPatchNumber / 4 + 1;
  224.                     l = (int)(Math.random() * MaxRocketPatchLength * 3 / 4) +
  225.                         MaxRocketPatchLength / 4 + 1;
  226.                     s = (long)(Math.random() * 10000);
  227.                 }
  228.  
  229.                 for (i = 0; i < MaxRocketNumber; ++i) {
  230.                     Rocket r = rocket[i];
  231.                     if (r.sleep && Math.random() * MaxRocketNumber * l < 1) {
  232.                         r.init(e, p, l, s);
  233.                         r.start();
  234.                     }
  235.  
  236.                     if (rocketsCreated)
  237.                         r.show(g);
  238.                 }
  239.             }
  240.         }
  241.     }
  242.  
  243.     /**
  244.      * Suspend the firework animation.
  245.      */
  246.     public void freezeRockets() {
  247.         suspend = true;
  248.     }
  249.  
  250.     /**
  251.      * Resume the firework animation.
  252.      */
  253.     public void unfreezeRockets() {
  254.         //Set suspend to false, in case freezeRockets was called after it was suspended
  255.         suspend = false;
  256.         launcher.resume();
  257.     }
  258.  
  259.     /**
  260.      * Paints a black background for this firework.
  261.      * This is a standard Java AWT method which typically gets called
  262.      * by the AWT to handle painting this component. It paints this component
  263.      * using the given graphics context. The graphics context clipping region
  264.      * is set to the bounding rectangle of this component and its <0,0>
  265.      * coordinate is this component's top-left corner.
  266.      *
  267.      * @param g the graphics context used for painting
  268.      * @see java.awt.Component#repaint
  269.      * @see java.awt.Component#update
  270.      */
  271.     public void paint(Graphics g) {
  272.         Dimension dim = size();
  273.         g.clipRect(0, 0, dim.width, dim.height);
  274.         g.setColor(Color.black);
  275.         g.fillRect(0, 0, dim.width + 1, dim.height + 1);
  276.     }
  277. }
  278.  
  279.  
  280. class Rocket {
  281.     public boolean sleep = true;
  282.  
  283.     private int energy,patch,length,
  284.              mx,my,
  285.              gravity,
  286.              ox,oy,
  287.              vx[],vy[],
  288.              x,y,
  289.              red,blue,green,
  290.              t;
  291.     private Random random;
  292.  
  293.     public Rocket(int a, int b, int g) {
  294.         mx = a;
  295.         my = b;
  296.         gravity = g;
  297.     }
  298.  
  299.     public void init(int e, int p, int l, long seed) {
  300.         int i;
  301.  
  302.         energy = e;
  303.         patch = p;
  304.         length = l;
  305.  
  306.         random = new Random(seed);
  307.  
  308.         vx = new int[patch];
  309.         vy = new int[patch];
  310.  
  311.         red = (int)(random.nextDouble() * 128) + 128;
  312.         blue = (int)(random.nextDouble() * 128) + 128;
  313.         green = (int)(random.nextDouble() * 128) + 128;
  314.  
  315.         ox = (int)(Math.random()*mx/2)+mx/4;
  316.         oy = (int)(Math.random()*my/2)+my/4;
  317.  
  318.         for(i = 0; i < patch; ++i) {
  319.             vx[i] = (int)(Math.random() * energy) - energy / 2;
  320.             vy[i] = (int)(Math.random() * energy * 7 / 8) - energy / 8;
  321.         }
  322.     }
  323.  
  324.     public void start() {
  325.         t = 0;
  326.         sleep = false;
  327.     }
  328.  
  329.     public void show(Graphics g) {
  330.         if (!sleep) {
  331.             if (t < length) {
  332.                 int i, c;
  333.                 double s;
  334.                 Color color;
  335.  
  336.                 c = (int)(random.nextDouble() * 64) - 32 + red;
  337.  
  338.                 if (c >= 0 && c < 256)
  339.                     red = c;
  340.  
  341.                 c = (int)(random.nextDouble() * 64) - 32 + blue;
  342.  
  343.                 if (c >= 0 && c < 256)
  344.                     blue = c;
  345.  
  346.                 c = (int)(random.nextDouble() * 64) - 32 + green;
  347.  
  348.                 if (c >= 0 && c < 256)
  349.                     green = c;
  350.  
  351.                 color = new Color(red, blue, green);
  352.  
  353.                 for (i = 0; i < patch; ++i) {
  354.                     s = (double)t / 100;
  355.                     x = (int)(vx[i] * s);
  356.                     y = (int)(vy[i] * s - gravity * s * s);
  357.  
  358.                     g.setColor(color);
  359.                     g.drawLine(ox + x, oy - y, ox + x, oy - y);
  360.  
  361.                     if (t >= length / 2) {
  362.                         for (int j = 0; j < 2; ++j)
  363.                         {
  364.                             s = (double)((t - length / 2) * 2 + j) / 100;
  365.                             x = (int)(vx[i] * s);
  366.                             y = (int)(vy[i] * s - gravity * s * s);
  367.  
  368.                             g.setColor(Color.black);
  369.                             g.drawLine(ox + x, oy - y, ox + x, oy - y);
  370.                         }
  371.                     }
  372.                 }
  373.  
  374.                 ++t;
  375.  
  376.             } else
  377.                 sleep = true;
  378.  
  379.         }
  380.     }
  381. }
  382.  
  383.